@ -35,11 +35,14 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
std : : any IRGenImpl : : visitNumber ( SysYParser : : NumberContext * ctx ) {
if ( ! ctx | | ! ctx - > IntConst ( ) ) {
throw std : : runtime_error ( FormatError ( " irgen " , " 当前仅支持整数字面量 " ) ) ;
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法数字字面量 " ) ) ;
if ( ctx - > IntConst ( ) ) {
return static_cast < ir : : Value * > ( builder_ . CreateConstInt ( std : : stoi ( ctx - > getText ( ) ) ) ) ;
}
return static_cast < ir : : Value * > (
builder_ . CreateConstInt ( std : : stoi ( ctx - > getText ( ) ) ) ) ;
if ( ctx - > FloatConst ( ) ) {
return static_cast < ir : : Value * > ( builder_ . CreateConstFloat ( std : : stof ( ctx - > getText ( ) ) ) ) ;
}
throw std : : runtime_error ( FormatError ( " irgen " , " 当前仅支持整数字面量或浮点字面量 " ) ) ;
}
// 变量使用的处理流程:
@ -55,11 +58,59 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
// find storage by matching declaration node stored in Sema context
// Sema stores types/decl contexts in IRGenContext maps; here we search storage_map_ by name
std : : string name = ctx - > Ident ( ) - > getText ( ) ;
// 优先使用按名称的快速映射
auto nit = name_map_ . find ( name ) ;
if ( nit ! = name_map_ . end ( ) ) {
// 支持下标访问:若有索引表达式列表,则生成 GEP + load
if ( ctx - > exp ( ) . size ( ) > 0 ) {
std : : vector < ir : : Value * > indices ;
// 首个索引用于穿过数组对象
indices . push_back ( builder_ . CreateConstInt ( 0 ) ) ;
for ( auto * e : ctx - > exp ( ) ) {
indices . push_back ( EvalExpr ( * e ) ) ;
}
auto * gep = builder_ . CreateGEP ( nit - > second , indices , module_ . GetContext ( ) . NextTemp ( ) ) ;
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( gep , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
// 如果映射到的是常量,直接返回常量值;否则按原来行为从槽位 load
if ( nit - > second - > IsConstant ( ) ) return nit - > second ;
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( nit - > second , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
for ( auto & kv : storage_map_ ) {
// kv.first is VarDefContext*, try to get Ident text
if ( kv . first & & kv . first - > Ident ( ) & & kv . first - > Ident ( ) - > getText ( ) = = name ) {
return static_cast < ir : : Value * > (
builder_ . CreateLoad ( kv . second , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
if ( ! kv . first ) continue ;
if ( auto * vdef = dynamic_cast < SysYParser : : VarDefContext * > ( kv . first ) ) {
if ( vdef - > Ident ( ) & & vdef - > Ident ( ) - > getText ( ) = = name ) {
if ( ctx - > exp ( ) . size ( ) > 0 ) {
std : : vector < ir : : Value * > indices ;
indices . push_back ( builder_ . CreateConstInt ( 0 ) ) ;
for ( auto * e : ctx - > exp ( ) ) indices . push_back ( EvalExpr ( * e ) ) ;
auto * gep = builder_ . CreateGEP ( kv . second , indices , module_ . GetContext ( ) . NextTemp ( ) ) ;
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( gep , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( kv . second , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
} else if ( auto * fparam = dynamic_cast < SysYParser : : FuncFParamContext * > ( kv . first ) ) {
if ( fparam - > Ident ( ) & & fparam - > Ident ( ) - > getText ( ) = = name ) {
if ( ctx - > exp ( ) . size ( ) > 0 ) {
std : : vector < ir : : Value * > indices ;
indices . push_back ( builder_ . CreateConstInt ( 0 ) ) ;
for ( auto * e : ctx - > exp ( ) ) indices . push_back ( EvalExpr ( * e ) ) ;
auto * gep = builder_ . CreateGEP ( kv . second , indices , module_ . GetContext ( ) . NextTemp ( ) ) ;
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( gep , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( kv . second , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
} else if ( auto * cdef = dynamic_cast < SysYParser : : ConstDefContext * > ( kv . first ) ) {
if ( cdef - > Ident ( ) & & cdef - > Ident ( ) - > getText ( ) = = name ) {
if ( ctx - > exp ( ) . size ( ) > 0 ) {
std : : vector < ir : : Value * > indices ;
indices . push_back ( builder_ . CreateConstInt ( 0 ) ) ;
for ( auto * e : ctx - > exp ( ) ) indices . push_back ( EvalExpr ( * e ) ) ;
auto * gep = builder_ . CreateGEP ( kv . second , indices , module_ . GetContext ( ) . NextTemp ( ) ) ;
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( gep , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
return static_cast < ir : : Value * > ( builder_ . CreateLoad ( kv . second , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
}
}
throw std : : runtime_error ( FormatError ( " irgen " , " 变量声明缺少存储槽位: " + name ) ) ;
@ -68,11 +119,190 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
std : : any IRGenImpl : : visitAddExp ( SysYParser : : AddExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法加法表达式 " ) ) ;
// left-associative: evaluate first two mulExp as a simple binary add
try {
// left-associative: fold across all mulExp operands
if ( ctx - > mulExp ( ) . size ( ) = = 1 ) return ctx - > mulExp ( 0 ) - > accept ( this ) ;
ir : : Value * lhs = std : : any_cast < ir : : Value * > ( ctx - > mulExp ( 0 ) - > accept ( this ) ) ;
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > mulExp ( 1 ) - > accept ( this ) ) ;
ir : : Value * cur = std : : any_cast < ir : : Value * > ( ctx - > mulExp ( 0 ) - > accept ( this ) ) ;
// extract operator sequence from text (in-order '+' or '-')
std : : string text = ctx - > getText ( ) ;
std : : vector < char > ops ;
for ( char c : text ) if ( c = = ' + ' | | c = = ' - ' ) ops . push_back ( c ) ;
for ( size_t i = 1 ; i < ctx - > mulExp ( ) . size ( ) ; + + i ) {
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > mulExp ( i ) - > accept ( this ) ) ;
char opch = ( i - 1 < ops . size ( ) ) ? ops [ i - 1 ] : ' + ' ;
ir : : Opcode op = ( opch = = ' - ' ) ? ir : : Opcode : : Sub : ir : : Opcode : : Add ;
cur = builder_ . CreateBinary ( op , cur , rhs , module_ . GetContext ( ) . NextTemp ( ) ) ;
}
return static_cast < ir : : Value * > ( cur ) ;
} catch ( const std : : exception & e ) {
LogInfo ( std : : string ( " [irgen] exception in visitAddExp text= " ) + ctx - > getText ( ) + " , err= " + e . what ( ) , std : : cerr ) ;
throw ;
}
}
std : : any IRGenImpl : : visitMulExp ( SysYParser : : MulExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法乘法表达式 " ) ) ;
if ( ctx - > unaryExp ( ) . size ( ) = = 1 ) return ctx - > unaryExp ( 0 ) - > accept ( this ) ;
ir : : Value * cur = std : : any_cast < ir : : Value * > ( ctx - > unaryExp ( 0 ) - > accept ( this ) ) ;
// extract operator sequence for '*', '/', '%'
std : : string text = ctx - > getText ( ) ;
std : : vector < char > ops ;
for ( char c : text ) if ( c = = ' * ' | | c = = ' / ' | | c = = ' % ' ) ops . push_back ( c ) ;
for ( size_t i = 1 ; i < ctx - > unaryExp ( ) . size ( ) ; + + i ) {
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > unaryExp ( i ) - > accept ( this ) ) ;
char opch = ( i - 1 < ops . size ( ) ) ? ops [ i - 1 ] : ' * ' ;
ir : : Opcode op = ir : : Opcode : : Mul ;
if ( opch = = ' / ' ) op = ir : : Opcode : : Div ;
else if ( opch = = ' % ' ) op = ir : : Opcode : : Mod ;
cur = builder_ . CreateBinary ( op , cur , rhs , module_ . GetContext ( ) . NextTemp ( ) ) ;
}
return static_cast < ir : : Value * > ( cur ) ;
}
std : : any IRGenImpl : : visitUnaryExp ( SysYParser : : UnaryExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法一元表达式 " ) ) ;
if ( ctx - > primaryExp ( ) ) return ctx - > primaryExp ( ) - > accept ( this ) ;
// function call: Ident '(' funcRParams? ')'
if ( ctx - > Ident ( ) & & ctx - > getText ( ) . find ( " ( " ) ! = std : : string : : npos ) {
std : : string fname = ctx - > Ident ( ) - > getText ( ) ;
std : : vector < ir : : Value * > args ;
if ( ctx - > funcRParams ( ) ) {
for ( auto * e : ctx - > funcRParams ( ) - > exp ( ) ) {
args . push_back ( EvalExpr ( * e ) ) ;
}
}
// find existing function or create an external declaration (assume int return)
ir : : Function * callee = nullptr ;
for ( auto & fup : module_ . GetFunctions ( ) ) {
if ( fup & & fup - > GetName ( ) = = fname ) { callee = fup . get ( ) ; break ; }
}
if ( ! callee ) {
std : : vector < std : : shared_ptr < ir : : Type > > param_types ;
for ( auto * a : args ) {
if ( a & & a - > IsFloat32 ( ) ) param_types . push_back ( ir : : Type : : GetFloat32Type ( ) ) ;
else param_types . push_back ( ir : : Type : : GetInt32Type ( ) ) ;
}
callee = module_ . CreateFunction ( fname , ir : : Type : : GetInt32Type ( ) , param_types ) ;
}
return static_cast < ir : : Value * > ( builder_ . CreateCall ( callee , args , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
if ( ctx - > unaryExp ( ) ) {
ir : : Value * val = std : : any_cast < ir : : Value * > ( ctx - > unaryExp ( ) - > accept ( this ) ) ;
if ( ctx - > unaryOp ( ) & & ctx - > unaryOp ( ) - > getText ( ) = = " + " ) return static_cast < ir : : Value * > ( val ) ;
else if ( ctx - > unaryOp ( ) & & ctx - > unaryOp ( ) - > getText ( ) = = " - " ) {
// 负号: 0 - val, 区分整型/浮点
if ( val - > IsFloat32 ( ) ) {
ir : : Value * zero = builder_ . CreateConstFloat ( 0.0f ) ;
return static_cast < ir : : Value * > ( builder_ . CreateSub ( zero , val , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
} else {
ir : : Value * zero = builder_ . CreateConstInt ( 0 ) ;
return static_cast < ir : : Value * > ( builder_ . CreateSub ( zero , val , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
}
if ( ctx - > unaryOp ( ) & & ctx - > unaryOp ( ) - > getText ( ) = = " ! " ) {
// logical not: produce int 1 if val == 0, else 0
if ( val - > IsFloat32 ( ) ) {
ir : : Value * zerof = builder_ . CreateConstFloat ( 0.0f ) ;
return static_cast < ir : : Value * > ( builder_ . CreateFCmp ( ir : : CmpInst : : EQ , val , zerof , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
} else {
ir : : Value * zero = builder_ . CreateConstInt ( 0 ) ;
return static_cast < ir : : Value * > ( builder_ . CreateICmp ( ir : : CmpInst : : EQ , val , zero , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
}
}
throw std : : runtime_error ( FormatError ( " irgen " , " 不支持的一元运算 " ) ) ;
}
std : : any IRGenImpl : : visitRelExp ( SysYParser : : RelExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法关系表达式 " ) ) ;
if ( ctx - > addExp ( ) . size ( ) = = 1 ) return ctx - > addExp ( 0 ) - > accept ( this ) ;
ir : : Value * lhs = std : : any_cast < ir : : Value * > ( ctx - > addExp ( 0 ) - > accept ( this ) ) ;
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > addExp ( 1 ) - > accept ( this ) ) ;
// 类型提升
if ( lhs - > IsFloat32 ( ) & & rhs - > IsInt32 ( ) ) {
if ( auto * ci = dynamic_cast < ir : : ConstantInt * > ( rhs ) ) {
rhs = builder_ . CreateConstFloat ( static_cast < float > ( ci - > GetValue ( ) ) ) ;
} else {
throw std : : runtime_error ( FormatError ( " irgen " , " 不支持 int 到 float 的隐式转换 " ) ) ;
}
} else if ( rhs - > IsFloat32 ( ) & & lhs - > IsInt32 ( ) ) {
if ( auto * ci = dynamic_cast < ir : : ConstantInt * > ( lhs ) ) {
lhs = builder_ . CreateConstFloat ( static_cast < float > ( ci - > GetValue ( ) ) ) ;
} else {
throw std : : runtime_error ( FormatError ( " irgen " , " 不支持 int 到 float 的隐式转换 " ) ) ;
}
}
ir : : CmpInst : : Predicate pred = ir : : CmpInst : : EQ ;
std : : string text = ctx - > getText ( ) ;
if ( text . find ( " <= " ) ! = std : : string : : npos ) pred = ir : : CmpInst : : LE ;
else if ( text . find ( " >= " ) ! = std : : string : : npos ) pred = ir : : CmpInst : : GE ;
else if ( text . find ( " < " ) ! = std : : string : : npos ) pred = ir : : CmpInst : : LT ;
else if ( text . find ( " > " ) ! = std : : string : : npos ) pred = ir : : CmpInst : : GT ;
if ( lhs - > IsFloat32 ( ) | | rhs - > IsFloat32 ( ) ) {
return static_cast < ir : : Value * > (
builder_ . CreateFCmp ( pred , lhs , rhs , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
return static_cast < ir : : Value * > (
builder_ . CreateBinary ( ir : : Opcode : : Add , lhs , rhs ,
module_ . GetContext ( ) . NextTemp ( ) ) ) ;
builder_ . CreateICmp ( pred , lhs , rhs , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
std : : any IRGenImpl : : visitEqExp ( SysYParser : : EqExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法相等表达式 " ) ) ;
if ( ctx - > relExp ( ) . size ( ) = = 1 ) return ctx - > relExp ( 0 ) - > accept ( this ) ;
ir : : Value * lhs = std : : any_cast < ir : : Value * > ( ctx - > relExp ( 0 ) - > accept ( this ) ) ;
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > relExp ( 1 ) - > accept ( this ) ) ;
// 类型提升
if ( lhs - > IsFloat32 ( ) & & rhs - > IsInt32 ( ) ) {
if ( auto * ci = dynamic_cast < ir : : ConstantInt * > ( rhs ) ) {
rhs = builder_ . CreateConstFloat ( static_cast < float > ( ci - > GetValue ( ) ) ) ;
} else {
throw std : : runtime_error ( FormatError ( " irgen " , " 不支持 int 到 float 的隐式转换 " ) ) ;
}
} else if ( rhs - > IsFloat32 ( ) & & lhs - > IsInt32 ( ) ) {
if ( auto * ci = dynamic_cast < ir : : ConstantInt * > ( lhs ) ) {
lhs = builder_ . CreateConstFloat ( static_cast < float > ( ci - > GetValue ( ) ) ) ;
} else {
throw std : : runtime_error ( FormatError ( " irgen " , " 不支持 int 到 float 的隐式转换 " ) ) ;
}
}
ir : : CmpInst : : Predicate pred = ir : : CmpInst : : EQ ;
std : : string text = ctx - > getText ( ) ;
if ( text . find ( " == " ) ! = std : : string : : npos ) pred = ir : : CmpInst : : EQ ;
else if ( text . find ( " != " ) ! = std : : string : : npos ) pred = ir : : CmpInst : : NE ;
if ( lhs - > IsFloat32 ( ) | | rhs - > IsFloat32 ( ) ) {
return static_cast < ir : : Value * > (
builder_ . CreateFCmp ( pred , lhs , rhs , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
return static_cast < ir : : Value * > (
builder_ . CreateICmp ( pred , lhs , rhs , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
std : : any IRGenImpl : : visitLAndExp ( SysYParser : : LAndExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法逻辑与表达式 " ) ) ;
if ( ctx - > eqExp ( ) . size ( ) = = 1 ) return ctx - > eqExp ( 0 ) - > accept ( this ) ;
// For simplicity, treat as int (0 or 1)
ir : : Value * lhs = std : : any_cast < ir : : Value * > ( ctx - > eqExp ( 0 ) - > accept ( this ) ) ;
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > eqExp ( 1 ) - > accept ( this ) ) ;
// lhs && rhs : (lhs != 0) && (rhs != 0)
ir : : Value * zero = builder_ . CreateConstInt ( 0 ) ;
ir : : Value * lhs_ne = builder_ . CreateICmp ( ir : : CmpInst : : NE , lhs , zero , module_ . GetContext ( ) . NextTemp ( ) ) ;
ir : : Value * rhs_ne = builder_ . CreateICmp ( ir : : CmpInst : : NE , rhs , zero , module_ . GetContext ( ) . NextTemp ( ) ) ;
return static_cast < ir : : Value * > (
builder_ . CreateMul ( lhs_ne , rhs_ne , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}
std : : any IRGenImpl : : visitLOrExp ( SysYParser : : LOrExpContext * ctx ) {
if ( ! ctx ) throw std : : runtime_error ( FormatError ( " irgen " , " 非法逻辑或表达式 " ) ) ;
if ( ctx - > lAndExp ( ) . size ( ) = = 1 ) return ctx - > lAndExp ( 0 ) - > accept ( this ) ;
ir : : Value * lhs = std : : any_cast < ir : : Value * > ( ctx - > lAndExp ( 0 ) - > accept ( this ) ) ;
ir : : Value * rhs = std : : any_cast < ir : : Value * > ( ctx - > lAndExp ( 1 ) - > accept ( this ) ) ;
// lhs || rhs : (lhs != 0) || (rhs != 0)
ir : : Value * zero = builder_ . CreateConstInt ( 0 ) ;
ir : : Value * lhs_ne = builder_ . CreateICmp ( ir : : CmpInst : : NE , lhs , zero , module_ . GetContext ( ) . NextTemp ( ) ) ;
ir : : Value * rhs_ne = builder_ . CreateICmp ( ir : : CmpInst : : NE , rhs , zero , module_ . GetContext ( ) . NextTemp ( ) ) ;
ir : : Value * or_val = builder_ . CreateAdd ( lhs_ne , rhs_ne , module_ . GetContext ( ) . NextTemp ( ) ) ;
ir : : Value * one = builder_ . CreateConstInt ( 1 ) ;
return static_cast < ir : : Value * > (
builder_ . CreateICmp ( ir : : CmpInst : : GE , or_val , one , module_ . GetContext ( ) . NextTemp ( ) ) ) ;
}