use crate::*;


pub enum SemanticToken {
    MacroDefinition,
    Invocation,
}

pub struct Invocation {
    pub name: String,
    pub bytecode: BytecodeSpan,
    pub arguments: Vec<InvocationArgument>,
}

pub struct BlockLiteral {
    pub tokens: Vec<BlockToken>,
}

pub struct BlockToken {
    pub source: SourceSpan,
    pub bytecode: BytecodeSpan,
    pub variant: BlockTokenVariant,
}

pub enum BlockTokenVariant {
    Invocation(Invocation),
    Word(PackedBinaryLiteral),
}

pub struct MacroDefinition {
    pub name: String,
    pub arguments: Vec<DefinitionArgument>,
    pub body: BlockLiteral,
}

// -------------------------------------------------------------------------- //

pub struct SemanticParseError {
    pub source: SourceSpan,
    pub variant: SemanticParseErrorVariant,
}

pub enum SemanticParseErrorVariant {

}

// -------------------------------------------------------------------------- //

pub struct DefinitionArgument {
    pub name: String,
    pub source: SourceSpan,
    pub variant: DefinitionArgumentVariant,
}

pub enum DefinitionArgumentVariant {
    Integer,
    Block,
}

pub struct InvocationArgument {
    pub source: SourceSpan,
    pub variant: InvocationArgumentVariant,
}

pub enum InvocationArgumentVariant {
    BlockLiteral(BlockLiteral),
    IntegerLiteral(usize),
    ConstantExpression(ConstantExpression),
    Invocation(Invocation),
}