@ -21,9 +21,55 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) {
// 待添加运行时库函数getint等
// generates globals and functions
auto type_i32 = Type : : getIntType ( ) ;
auto type_f32 = Type : : getFloatType ( ) ;
auto type_void = Type : : getVoidType ( ) ;
auto type_i32p = Type : : getPointerType ( type_i32 ) ;
auto type_f32p = Type : : getPointerType ( type_f32 ) ;
visitChildren ( ctx ) ;
// return the IR module
//runtime library
module - > createFunction ( " getint " , Type : : getFunctionType ( type_i32 , { } ) ) ;
module - > createFunction ( " getch " , Type : : getFunctionType ( type_i32 , { } ) ) ;
module - > createFunction ( " getfloat " , Type : : getFunctionType ( type_f32 , { } ) ) ;
symbols_table . insert ( " getint " , module - > getFunction ( " getint " ) ) ;
symbols_table . insert ( " getch " , module - > getFunction ( " getch " ) ) ;
symbols_table . insert ( " getfloat " , module - > getFunction ( " getfloat " ) ) ;
module - > createFunction ( " getarray " , Type : : getFunctionType ( type_i32 , { type_i32p } ) ) ;
module - > createFunction ( " getfarray " , Type : : getFunctionType ( type_i32 , { type_f32p } ) ) ;
symbols_table . insert ( " getarray " , module - > getFunction ( " getarray " ) ) ;
symbols_table . insert ( " getfarray " , module - > getFunction ( " getfarray " ) ) ;
module - > createFunction ( " putint " , Type : : getFunctionType ( type_void , { type_i32 } ) ) ;
module - > createFunction ( " putch " , Type : : getFunctionType ( type_void , { type_i32 } ) ) ;
module - > createFunction ( " putfloat " , Type : : getFunctionType ( type_void , { type_f32 } ) ) ;
symbols_table . insert ( " putint " , module - > getFunction ( " putint " ) ) ;
symbols_table . insert ( " putch " , module - > getFunction ( " putch " ) ) ;
symbols_table . insert ( " putfloat " , module - > getFunction ( " putfloat " ) ) ;
module - > createFunction ( " putarray " , Type : : getFunctionType ( type_void , { type_i32 , type_i32p } ) ) ;
module - > createFunction ( " putfarray " , Type : : getFunctionType ( type_void , { type_i32 , type_f32p } ) ) ;
symbols_table . insert ( " putarray " , module - > getFunction ( " putarray " ) ) ;
symbols_table . insert ( " putfarray " , module - > getFunction ( " putfarray " ) ) ;
module - > createFunction ( " putf " , Type : : getFunctionType ( type_void , { } ) ) ;
symbols_table . insert ( " putf " , module - > getFunction ( " putf " ) ) ;
module - > createFunction ( " starttime " , Type : : getFunctionType ( type_void , { type_i32 } ) ) ;
module - > createFunction ( " stoptime " , Type : : getFunctionType ( type_void , { type_i32 } ) ) ;
symbols_table . insert ( " starttime " , module - > getFunction ( " starttime " ) ) ;
symbols_table . insert ( " stoptime " , module - > getFunction ( " stoptime " ) ) ;
// visit all decls and funcDefs
for ( auto decl : ctx - > decl ( ) ) {
decl - > accept ( this ) ;
}
for ( auto funcDef : ctx - > funcDef ( ) ) {
builder = IRBuilder ( ) ;
printf ( " entry funcDef \n " ) ;
funcDef - > accept ( this ) ;
}
// return the IR module ?
return pModule ;
}
@ -37,39 +83,706 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) {
* we consider them together? not sure
*/
std : : any SysYIRGenerator : : visitDecl ( SysYParser : : DeclContext * ctx ) {
if ( ctx - > constDecl ( ) ) {
if ( ctx - > constDecl ( ) )
return visitConstDecl ( ctx - > constDecl ( ) ) ;
} else if ( ctx - > varDecl ( ) ) {
else if ( ctx - > varDecl ( ) )
return visitVarDecl ( ctx - > varDecl ( ) ) ;
}
return nullptr ;
std : : cerr < < " error unkown decl " < < ctx - > getText ( ) < < std : : endl ;
return std : : any ( ) ;
}
/*
* @brief: visit constdecl
* @details:
* constDecl: CONST bType constDef (COMMA constDef)* SEMI;
* constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?;
*/
std : : any SysYIRGenerator : : visitConstDecl ( SysYParser : : ConstDeclContext * ctx ) {
a uto type = Type : : getPointerType ( any_cast < Type * > ( ctx - > bType ( ) - > accept ( this ) ) ) ;
if ( symbols_table . isModuleScope ( ) )
visitConstGlobalDecl ( ctx , type ) ;
else
visitConstLocalDecl ( ctx , type ) ;
co ut < < " visitconstDecl " < < endl ;
current_type = any_cast < Type * > ( ctx - > bType ( ) - > accept ( this ) ) ;
for ( auto constDef : ctx - > constDef ( ) ) {
constDef - > accept ( this ) ;
}
return std : : any ( ) ;
}
/*
* @brief: visit btype
* @details:
* bType: INT | FLOAT;
*/
std : : any SysYIRGenerator : : visitBType ( SysYParser : : BTypeContext * ctx ) {
return ctx - > INT ( ) ? Type : : getIntType ( ) : Type : : getFloatType ( ) ;
if ( ctx - > INT ( ) )
return Type : : getIntType ( ) ;
else if ( ctx - > FLOAT ( ) )
return Type : : getFloatType ( ) ;
std : : cerr < < " error: unknown type " < < ctx - > getText ( ) < < std : : endl ;
return std : : any ( ) ;
}
// std::any visitConstDef(SysYParser::ConstDefContext *ctx);
/*
* @brief: visit constDef
* @details:
* constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?;
* constInitVal: constExp | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE;
*/
std : : any SysYIRGenerator : : visitConstDef ( SysYParser : : ConstDefContext * ctx ) {
auto name = ctx - > Ident ( ) - > getText ( ) ;
auto type = current_type ;
auto init = ctx - > constInitVal ( ) ? any_cast < Value * > ( ctx - > constInitVal ( ) - > accept ( this ) ) : ( Value * ) nullptr ;
if ( ctx - > constExp ( ) . empty ( ) ) {
//scalar
if ( init ) {
if ( symbols_table . isModuleScope ( ) ) {
assert ( init - > isConstant ( ) & & " global must be initialized by constant " ) ;
auto global = module - > createGlobalValue ( name , type , { } , init ) ;
symbols_table . insert ( name , global ) ;
}
else {
auto alloca = builder . createAllocaInst ( type , { } , name ) ;
auto store = builder . createStoreInst ( init , alloca ) ;
symbols_table . insert ( name , alloca ) ;
}
}
else {
assert ( false & & " const without initialization " ) ;
}
}
else {
//array
std : : cerr < < " array constDef not implemented yet " < < std : : endl ;
}
printf ( " visitConstDef %s \n " , name . c_str ( ) ) ;
return std : : any ( ) ;
}
/*
* @brief: visit constInitVal
* @details:
* constInitVal: constExp
* | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE;
*/
std : : any SysYIRGenerator : : visitConstInitVal ( SysYParser : : ConstInitValContext * ctx ) {
Value * initvalue ;
if ( ctx - > constExp ( ) )
initvalue = any_cast < Value * > ( ctx - > constExp ( ) - > accept ( this ) ) ;
else {
//还未实现数组初始化等功能待验证
std : : cerr < < " array initvalue not implemented yet " < < std : : endl ;
// auto numConstInitVals = ctx->constInitVal().size();
// vector<Value*> initvalues;
// for(int i = 0; i < numConstInitVals; i++)
// initvalues.push_back(any_cast<Value*>(ctx->constInitVal(i)->accept(this)));
// initvalue = ConstantValue::getArray(initvalues);
}
return initvalue ;
}
/*
* @brief: visit function type
* @details:
* funcType: VOID | INT | FLOAT;
*/
std : : any SysYIRGenerator : : visitFuncType ( SysYParser : : FuncTypeContext * ctx ) {
if ( ctx - > INT ( ) )
return Type : : getIntType ( ) ;
else if ( ctx - > FLOAT ( ) )
return Type : : getFloatType ( ) ;
else if ( ctx - > VOID ( ) )
return Type : : getVoidType ( ) ;
std : : cerr < < " invalid function type: " < < ctx - > getText ( ) < < std : : endl ;
return std : : any ( ) ;
}
/*
* @brief: visit function define
* @details:
* funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt;
* funcFParams: funcFParam (COMMA funcFParam)*;
* funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?;
* entry -> next -> others -> exit
* entry: allocas, br
* next: retval, params, br
* other: blockStmt init block
* exit: load retval, ret
*/
std : : any SysYIRGenerator : : visitFuncDef ( SysYParser : : FuncDefContext * ctx ) {
auto funcName = ctx - > Ident ( ) - > getText ( ) ;
auto returnType = any_cast < Type * > ( ctx - > funcType ( ) - > accept ( this ) ) ;
auto func = module - > getFunction ( funcName ) ;
cout < < " func: " ;
returnType - > print ( cout ) ;
cout < < ' ' < < funcName . c_str ( ) < < endl ;
vector < Type * > paramTypes ;
vector < string > paramNames ;
if ( ctx - > funcFParams ( ) ) {
for ( auto funcParam : ctx - > funcFParams ( ) - > funcFParam ( ) ) {
Type * paramType = any_cast < Type * > ( funcParam - > bType ( ) - > accept ( this ) ) ;
paramTypes . push_back ( paramType ) ;
paramNames . push_back ( funcParam - > Ident ( ) - > getText ( ) ) ;
}
}
auto funcType = FunctionType : : get ( returnType , paramTypes ) ;
auto function = module - > createFunction ( funcName , funcType ) ;
SymbolTable : : FunctionScope scope ( symbols_table ) ;
BasicBlock * entryblock = function - > getEntryBlock ( ) ;
for ( size_t i = 0 ; i < paramTypes . size ( ) ; i + + )
entryblock - > createArgument ( paramTypes [ i ] , paramNames [ i ] ) ;
for ( auto & arg : entryblock - > getArguments ( ) )
symbols_table . insert ( arg - > getName ( ) , arg . get ( ) ) ;
builder . setPosition ( entryblock , entryblock - > end ( ) ) ;
ctx - > blockStmt ( ) - > accept ( this ) ;
return std : : any ( ) ;
}
/*
* @brief: visit varDecl
* @details:
* varDecl: bType varDef (COMMA varDef)* SEMI;
*/
std : : any SysYIRGenerator : : visitVarDecl ( SysYParser : : VarDeclContext * ctx ) {
cout < < " visitVarDecl " < < endl ;
current_type = any_cast < Type * > ( ctx - > bType ( ) - > accept ( this ) ) ;
for ( auto varDef : ctx - > varDef ( ) ) {
varDef - > accept ( this ) ;
}
return std : : any ( ) ;
}
/*
* @brief: visit varDef
* @details:
* varDef: Ident (LBRACK constExp RBRACK)* (ASSIGN initVal)?;
*/
std : : any SysYIRGenerator : : visitVarDef ( SysYParser : : VarDefContext * ctx ) {
auto name = ctx - > Ident ( ) - > getText ( ) ;
auto type = current_type ;
auto init = ctx - > initVal ( ) ? any_cast < Value * > ( ctx - > initVal ( ) - > accept ( this ) ) : ( Value * ) nullptr ;
cout < < " vardef: " ;
current_type - > print ( cout ) ;
cout < < ' ' < < name < < endl ;
if ( ctx - > constExp ( ) . empty ( ) ) {
//scalar
if ( symbols_table . isModuleScope ( ) ) {
if ( init )
assert ( init - > isConstant ( ) & & " global must be initialized by constant " ) ;
auto global = module - > createGlobalValue ( name , type , { } , init ) ;
symbols_table . insert ( name , global ) ;
cout < < " add module var " < < name < < " inited by " ;
init - > print ( cout ) ;
cout < < ' \n ' ;
}
else {
auto alloca = builder . createAllocaInst ( type , { } , name ) ;
auto store = ( StoreInst * ) nullptr ;
if ( init )
store = builder . createStoreInst ( init , alloca ) ;
symbols_table . insert ( name , alloca ) ;
cout < < " add local var " < < name ;
if ( init ) {
cout < < " inited by " ;
init - > print ( cout ) ;
}
cout < < ' \n ' ;
}
}
else {
//array
std : : cerr < < " array varDef not implemented yet " < < std : : endl ;
}
return std : : any ( ) ;
}
/*
* @brief: visit initVal
* @details:
* initVal: exp | LBRACE (initVal (COMMA initVal)*)? RBRACE;
*/
std : : any SysYIRGenerator : : visitInitVal ( SysYParser : : InitValContext * ctx ) {
Value * initvalue ;
if ( ctx - > exp ( ) )
initvalue = any_cast < Value * > ( ctx - > exp ( ) - > accept ( this ) ) ;
else {
//还未实现数组初始化等功能待验证
std : : cerr < < " array initvalue not implemented yet " < < std : : endl ;
// auto numConstInitVals = ctx->constInitVal().size();
// vector<Value*> initvalues;
// for(int i = 0; i < numConstInitVals; i++)
// initvalues.push_back(any_cast<Value*>(ctx->constInitVal(i)->accept(this)));
// initvalue = ConstantValue::getArray(initvalues);
}
return initvalue ;
}
// std::any SysYIRGenerator::visitFuncFParams(SysYParser::FuncFParamsContext* ctx){
// return visitChildren(ctx);
// }
// std::any SysYIRGenerator::visitFuncFParam(SysYParser::FuncFParamContext *ctx) {
// return visitChildren(ctx);
// }
/*
* @brief: visit blockStmt
* @details:
* blockStmt: LBRACE blockItem* RBRACE;
* blockItem: decl | stmt;
*/
std : : any SysYIRGenerator : : visitBlockStmt ( SysYParser : : BlockStmtContext * ctx ) {
SymbolTable : : BlockScope scope ( symbols_table ) ;
for ( auto item : ctx - > blockItem ( ) ) {
item - > accept ( this ) ;
// if(builder.getBasicBlock()->isTerminal()){
// break;
// }
}
return std : : any ( ) ;
}
/*
* @brief: visit ifstmt
* @details:
* ifStmt: IF LPAREN cond RPAREN stmt (ELSE stmt)?;
*/
std : : any SysYIRGenerator : : visitIfStmt ( SysYParser : : IfStmtContext * ctx ) {
auto condition = any_cast < Value * > ( ctx - > cond ( ) - > accept ( this ) ) ;
auto thenBlock = builder . getBasicBlock ( ) - > getParent ( ) - > addBasicBlock ( " then " ) ;
auto elseBlock = builder . getBasicBlock ( ) - > getParent ( ) - > addBasicBlock ( " else " ) ;
auto condbr = builder . createCondBrInst ( condition , thenBlock , elseBlock , { } , { } ) ;
builder . setPosition ( thenBlock , thenBlock - > end ( ) ) ;
ctx - > stmt ( 0 ) - > accept ( this ) ;
if ( ctx - > ELSE ( ) ) {
builder . setPosition ( elseBlock , elseBlock - > end ( ) ) ;
ctx - > stmt ( 1 ) - > accept ( this ) ;
}
//无条件跳转到下一个基本块
// builder.createUncondBrInst(builder.getBasicBlock()->getParent()->addBasicBlock("next"),{});
return std : : any ( ) ;
}
/*
* @brief: visit whilestmt
* @details:
* whileStmt: WHILE LPAREN cond RPAREN stmt;
*/
std : : any SysYIRGenerator : : visitWhileStmt ( SysYParser : : WhileStmtContext * ctx ) {
//需要解决一个函数多个循环的命名问题
auto header = builder . getBasicBlock ( ) - > getParent ( ) - > addBasicBlock ( " header " ) ;
auto body = builder . getBasicBlock ( ) - > getParent ( ) - > addBasicBlock ( " body " ) ;
auto exit = builder . getBasicBlock ( ) - > getParent ( ) - > addBasicBlock ( " exit " ) ;
SymbolTable : : BlockScope scope ( symbols_table ) ;
{ // visit header block
builder . setPosition ( header , header - > end ( ) ) ;
auto cond = any_cast < Value * > ( ctx - > cond ( ) - > accept ( this ) ) ;
auto condbr = builder . createCondBrInst ( cond , body , exit , { } , { } ) ;
}
{ // visit body block
builder . setPosition ( body , body - > end ( ) ) ;
ctx - > stmt ( ) - > accept ( this ) ;
auto uncondbr = builder . createUncondBrInst ( header , { } ) ;
}
// visit exit block
builder . setPosition ( exit , exit - > end ( ) ) ;
//无条件跳转到下一个基本块以及一些参数传递
return std : : any ( ) ;
}
/*
* @brief: visit breakstmt
* @details:
* breakStmt: BREAK SEMICOLON;
*/
std : : any SysYIRGenerator : : visitBreakStmt ( SysYParser : : BreakStmtContext * ctx ) {
//如何获取break所在body对应的header块
return std : : any ( ) ;
}
/*
* @brief Visit ReturnStmt
* returnStmt: RETURN exp? SEMICOLON;
*/
std : : any SysYIRGenerator : : visitReturnStmt ( SysYParser : : ReturnStmtContext * ctx ) {
// auto value = ctx->exp() ? any_cast_Value(visit(ctx->exp())) : nullptr;
auto value = ctx - > exp ( ) ? any_cast < Value * > ( ctx - > exp ( ) - > accept ( this ) ) : nullptr ;
const auto func = builder . getBasicBlock ( ) - > getParent ( ) ;
assert ( func & & " ret stmt block parent err! " ) ;
// 匹配 返回值类型 与 函数定义类型
if ( func - > getReturnType ( ) - > isVoid ( ) ) {
if ( ctx - > exp ( ) )
assert ( false & & " the returned value is not matching the function " ) ;
auto ret = builder . createReturnInst ( ) ;
return std : : any ( ) ;
}
assert ( ctx - > exp ( ) & & " the returned value is not matching the function " ) ;
auto ret = builder . createReturnInst ( value ) ;
//需要增加无条件跳转吗
return std : : any ( ) ;
}
/*
* @brief: visit continuestmt
* @details:
* continueStmt: CONTINUE SEMICOLON;
*/
std : : any SysYIRGenerator : : visitContinueStmt ( SysYParser : : ContinueStmtContext * ctx ) {
//如何获取continue所在body对应的header块
return std : : any ( ) ;
}
/*
* @brief visit assign stmt
* @details:
* assignStmt: lValue ASSIGN exp SEMICOLON
*/
std : : any SysYIRGenerator : : visitAssignStmt ( SysYParser : : AssignStmtContext * ctx ) {
cout < < " visitassignstme : \n " ;
auto lvalue = any_cast < Value * > ( ctx - > lValue ( ) - > accept ( this ) ) ;
cout < < ' lval : ( ' < < lvalue - > getName ( ) ;
auto rvalue = any_cast < Value * > ( ctx - > exp ( ) - > accept ( this ) ) ;
//可能要考虑类型转换例如int a = 1.0
builder . createStoreInst ( rvalue , lvalue ) ;
cout < < ' ) = rval ( ' < < rvalue - > getName ( ) ;
return std : : any ( ) ;
}
/*
* @brief: visit lValue
* @details:
* lValue: Ident (LBRACK exp RBRACK)*;
*/
std : : any SysYIRGenerator : : visitLValue ( SysYParser : : LValueContext * ctx ) {
auto name = ctx - > Ident ( ) - > getText ( ) ;
Value * value = symbols_table . lookup ( name ) ;
assert ( value & & " lvalue not found " ) ;
if ( ctx - > exp ( ) . size ( ) = = 0 ) {
//scalar
cout < < " lvalue: " < < name < < endl ;
return value ;
}
else {
//array
std : : cerr < < " array lvalue not implemented yet " < < std : : endl ;
}
std : : cerr < < " error lvalue " < < ctx - > getText ( ) < < std : : endl ;
return std : : any ( ) ;
}
std : : any SysYIRGenerator : : visitNumber ( SysYParser : : NumberContext * ctx ) {
ConstantValue * res = nullptr ;
if ( auto iLiteral = ctx - > ILITERAL ( ) ) {
/* 基数 (8, 10, 16) */
const auto text = iLiteral - > getText ( ) ;
int base = 10 ;
if ( text . find ( " 0x " ) = = 0 | | text . find ( " 0X " ) = = 0 ) {
base = 16 ;
} else if ( text . find ( " 0b " ) = = 0 | | text . find ( " 0B " ) = = 0 ) {
base = 2 ;
} else if ( text . find ( " 0 " ) = = 0 ) {
base = 8 ;
}
res = ConstantValue : : get ( ( int ) std : : stol ( text , 0 , base ) ) ;
} else if ( auto fLiteral = ctx - > FLITERAL ( ) ) {
const auto text = fLiteral - > getText ( ) ;
res = ConstantValue : : get ( ( float ) std : : stof ( text ) ) ;
}
return res ;
}
/*
* @brief: visit call
* @details:
* call: Ident LPAREN funcRParams? RPAREN;
*/
std : : any SysYIRGenerator : : visitCall ( SysYParser : : CallContext * ctx ) {
auto funcName = ctx - > Ident ( ) - > getText ( ) ;
auto func = module - > getFunction ( funcName ) ;
assert ( func & & " function not found " ) ;
//需要做类型检查和转换
std : : vector < Value * > args ;
if ( ctx - > funcRParams ( ) ) {
for ( auto exp : ctx - > funcRParams ( ) - > exp ( ) ) {
args . push_back ( any_cast < Value * > ( exp - > accept ( this ) ) ) ;
}
}
auto call = builder . createCallInst ( func , args ) ;
return call ;
}
/*
* @brief: visit unexp
* @details:
* unExp: unaryOp unaryExp
*/
std : : any SysYIRGenerator : : visitUnExp ( SysYParser : : UnExpContext * ctx ) {
Value * res = nullptr ;
auto op = ctx - > unaryOp ( ) - > getText ( ) ;
auto exp = any_cast < Value * > ( ctx - > unaryExp ( ) - > accept ( this ) ) ;
if ( ctx - > unaryOp ( ) - > ADD ( ) ) {
res = exp ;
}
else if ( ctx - > unaryOp ( ) - > SUB ( ) ) {
res = builder . createNegInst ( exp , exp - > getName ( ) ) ;
}
else if ( ctx - > unaryOp ( ) - > NOT ( ) ) {
//not将非零值转换为0, 零值转换为1
res = builder . createNotInst ( exp , exp - > getName ( ) ) ;
}
return res ;
}
/*
* @brief: visit mulexp
* @details:
* mulExp: unaryExp ((MUL | DIV | MOD) unaryExp)*
*/
std : : any SysYIRGenerator : : visitMulExp ( SysYParser : : MulExpContext * ctx ) {
Value * res = nullptr ;
auto lhs = any_cast < Value * > ( ctx - > unaryExp ( 0 ) - > accept ( this ) ) ;
if ( ctx - > unaryExp ( ) . size ( ) = = 1 ) {
res = lhs ;
}
else {
for ( size_t i = 1 ; i < ctx - > unaryExp ( ) . size ( ) ; i + + ) {
auto unaryexp = ctx - > unaryExp ( i ) ;
auto rhs = any_cast < Value * > ( unaryexp - > accept ( this ) ) ;
auto opNode = dynamic_cast < antlr4 : : tree : : TerminalNode * > ( ctx - > children [ 2 * i + 1 ] ) ;
if ( opNode - > getText ( ) = = " * " ) {
res = builder . createMulInst ( lhs , rhs , lhs - > getName ( ) + " * " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " / " ) {
res = builder . createDivInst ( lhs , rhs , lhs - > getName ( ) + " / " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " % " ) {
std : : cerr < < " mod not implemented yet " < < std : : endl ;
// res = builder.createModInst(lhs, rhs, lhs->getName() + "%" + rhs->getName());
}
}
}
return res ;
}
/*
* @brief: visit addexp
* @details:
* addExp: mulExp ((ADD | SUB) mulExp)*
*/
std : : any SysYIRGenerator : : visitAddExp ( SysYParser : : AddExpContext * ctx ) {
Value * res = nullptr ;
auto lhs = any_cast < Value * > ( ctx - > mulExp ( 0 ) - > accept ( this ) ) ;
if ( ctx - > mulExp ( ) . size ( ) = = 1 ) {
res = lhs ;
}
else {
for ( size_t i = 1 ; i < ctx - > mulExp ( ) . size ( ) ; i + + ) {
auto mulexp = ctx - > mulExp ( i ) ;
auto rhs = any_cast < Value * > ( mulexp - > accept ( this ) ) ;
auto opNode = dynamic_cast < antlr4 : : tree : : TerminalNode * > ( ctx - > children [ 2 * i + 1 ] ) ;
if ( opNode - > getText ( ) = = " + " ) {
res = builder . createAddInst ( lhs , rhs , lhs - > getName ( ) + " + " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " - " ) {
res = builder . createSubInst ( lhs , rhs , lhs - > getName ( ) + " - " + rhs - > getName ( ) ) ;
}
}
}
return res ;
}
/*
* @brief: visit relexp
* @details:
* relExp: addExp ((LT | GT | LE | GE) addExp)*
*/
std : : any SysYIRGenerator : : visitRelExp ( SysYParser : : RelExpContext * ctx ) {
Value * res = nullptr ;
auto lhs = any_cast < Value * > ( ctx - > addExp ( 0 ) - > accept ( this ) ) ;
if ( ctx - > addExp ( ) . size ( ) = = 1 ) {
res = lhs ;
}
else {
for ( size_t i = 1 ; i < ctx - > addExp ( ) . size ( ) ; i + + ) {
auto addexp = ctx - > addExp ( i ) ;
auto rhs = any_cast < Value * > ( addexp - > accept ( this ) ) ;
auto opNode = dynamic_cast < antlr4 : : tree : : TerminalNode * > ( ctx - > children [ 2 * i + 1 ] ) ;
if ( lhs - > getType ( ) ! = rhs - > getType ( ) ) {
std : : cerr < < " type mismatch:type check not implemented " < < std : : endl ;
}
Type * type = lhs - > getType ( ) ;
if ( opNode - > getText ( ) = = " < " ) {
if ( type - > isInt ( ) )
res = builder . createICmpLTInst ( lhs , rhs , lhs - > getName ( ) + " < " + rhs - > getName ( ) ) ;
else if ( type - > isFloat ( ) )
res = builder . createFCmpLTInst ( lhs , rhs , lhs - > getName ( ) + " < " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " > " ) {
if ( type - > isInt ( ) )
res = builder . createICmpGTInst ( lhs , rhs , lhs - > getName ( ) + " > " + rhs - > getName ( ) ) ;
else if ( type - > isFloat ( ) )
res = builder . createFCmpGTInst ( lhs , rhs , lhs - > getName ( ) + " > " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " <= " ) {
if ( type - > isInt ( ) )
res = builder . createICmpLEInst ( lhs , rhs , lhs - > getName ( ) + " <= " + rhs - > getName ( ) ) ;
else if ( type - > isFloat ( ) )
res = builder . createFCmpLEInst ( lhs , rhs , lhs - > getName ( ) + " <= " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " >= " ) {
if ( type - > isInt ( ) )
res = builder . createICmpGEInst ( lhs , rhs , lhs - > getName ( ) + " >= " + rhs - > getName ( ) ) ;
else if ( type - > isFloat ( ) )
res = builder . createFCmpGEInst ( lhs , rhs , lhs - > getName ( ) + " >= " + rhs - > getName ( ) ) ;
}
}
}
return res ;
}
/*
* @brief: visit eqexp
* @details:
* eqExp: relExp ((EQ | NEQ) relExp)*
*/
std : : any SysYIRGenerator : : visitEqExp ( SysYParser : : EqExpContext * ctx ) {
Value * res = nullptr ;
auto lhs = any_cast < Value * > ( ctx - > relExp ( 0 ) - > accept ( this ) ) ;
if ( ctx - > relExp ( ) . size ( ) = = 1 ) {
res = lhs ;
}
else {
for ( size_t i = 1 ; i < ctx - > relExp ( ) . size ( ) ; i + + ) {
auto relexp = ctx - > relExp ( i ) ;
auto rhs = any_cast < Value * > ( relexp - > accept ( this ) ) ;
auto opNode = dynamic_cast < antlr4 : : tree : : TerminalNode * > ( ctx - > children [ 2 * i + 1 ] ) ;
if ( lhs - > getType ( ) ! = rhs - > getType ( ) ) {
std : : cerr < < " type mismatch:type check not implemented " < < std : : endl ;
}
Type * type = lhs - > getType ( ) ;
if ( opNode - > getText ( ) = = " == " ) {
if ( type - > isInt ( ) )
res = builder . createICmpEQInst ( lhs , rhs , lhs - > getName ( ) + " == " + rhs - > getName ( ) ) ;
else if ( type - > isFloat ( ) )
res = builder . createFCmpEQInst ( lhs , rhs , lhs - > getName ( ) + " == " + rhs - > getName ( ) ) ;
}
else if ( opNode - > getText ( ) = = " != " ) {
if ( type - > isInt ( ) )
res = builder . createICmpNEInst ( lhs , rhs , lhs - > getName ( ) + " != " + rhs - > getName ( ) ) ;
else if ( type - > isFloat ( ) )
res = builder . createFCmpNEInst ( lhs , rhs , lhs - > getName ( ) + " != " + rhs - > getName ( ) ) ;
}
}
}
return res ;
}
/*
* @brief: visit lAndexp
* @details:
* lAndExp: eqExp (AND eqExp)*
*/
std : : any SysYIRGenerator : : visitLAndExp ( SysYParser : : LAndExpContext * ctx ) {
auto currentBlock = builder . getBasicBlock ( ) ;
// auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum));
auto falseBlock = currentBlock - > getParent ( ) - > addBasicBlock ( " falseland " + std : : to_string ( + + falseBlockNum ) ) ;
auto value = any_cast < Value * > ( ctx - > eqExp ( 0 ) - > accept ( this ) ) ;
auto trueBlock = currentBlock ;
for ( size_t i = 1 ; i < ctx - > eqExp ( ) . size ( ) ; i + + ) {
trueBlock = trueBlock - > getParent ( ) - > addBasicBlock ( " trueland " + std : : to_string ( + + trueBlockNum ) ) ;
builder . createCondBrInst ( value , currentBlock , falseBlock , { } , { } ) ;
builder . setPosition ( trueBlock , trueBlock - > end ( ) ) ;
value = any_cast < Value * > ( ctx - > eqExp ( i ) - > accept ( this ) ) ;
}
//结构trueblk条件跳转到falseblk
// - trueBlock1->trueBlock2->trueBlock3->...->trueBlockn->nextblk
//entry-|
// -falseBlock->nextblk
//需要在最后一个trueblock的末尾加上无条件跳转到下一个基本块的指令
// builder.createCondBrInst(value, trueBlock, falseBlock, {}, {});
return std : : any ( ) ;
}
/*
* @brief: visit lOrexp
* @details:
* lOrExp: lAndExp (OR lAndExp)*
*/
std : : any SysYIRGenerator : : visitLOrExp ( SysYParser : : LOrExpContext * ctx ) {
auto currentBlock = builder . getBasicBlock ( ) ;
auto trueBlock = currentBlock - > getParent ( ) - > addBasicBlock ( " trueland " + std : : to_string ( + + trueBlockNum ) ) ;
auto value = any_cast < Value * > ( ctx - > lAndExp ( 0 ) - > accept ( this ) ) ;
auto falseBlock = currentBlock ;
for ( size_t i = 1 ; i < ctx - > lAndExp ( ) . size ( ) ; i + + ) {
falseBlock = currentBlock - > getParent ( ) - > addBasicBlock ( " falseland " + std : : to_string ( + + falseBlockNum ) ) ;
builder . createCondBrInst ( value , trueBlock , falseBlock , { } , { } ) ;
builder . setPosition ( falseBlock , falseBlock - > end ( ) ) ;
value = any_cast < Value * > ( ctx - > lAndExp ( i ) - > accept ( this ) ) ;
}
//结构trueblk条件跳转到falseblk
// - falseBlock1->falseBlock2->falseBlock3->...->falseBlockn->nextblk
//entry-|
// -trueBlock->nextblk
//需要在最后一个falseblock的末尾加上无条件跳转到下一个基本块的指令
// builder.createCondBrInst(value, trueBlock, falseBlock, {}, {});
return std : : any ( ) ;
}
/*
* @brief: visit constexp
* @details:
* constExp: addExp;
*/
std : : any SysYIRGenerator : : visitConstExp ( SysYParser : : ConstExpContext * ctx ) {
ConstantValue * res = nullptr ;
auto value = any_cast < Value * > ( ctx - > addExp ( ) - > accept ( this ) ) ;
if ( isa < ConstantValue > ( value ) ) {
res = dynamic_cast < ConstantValue * > ( value ) ;
}
else {
std : : cerr < < " error constexp " < < ctx - > getText ( ) < < std : : endl ;
}
return res ;
}
/* begin
std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) {
std::vector<Value *> values;
for (auto constDef : ctx->constDef()) {
@ -266,93 +979,7 @@ std::any SysYIRGenerator::visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Typ
}
return values;
}
/*
* @brief: visit constInitVal
* @details:
* constInitVal: constExp
* | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE;
*/
std : : any visitConstInitVal ( SysYParser : : ConstInitValContext * ctx ) {
}
/*
* @brief: visit function type
* @details:
* funcType: VOID | INT | FLOAT;
*/
std : : any SysYIRGenerator : : visitFuncType ( SysYParser : : FuncTypeContext * ctx ) {
return ctx - > INT ( ) ? Type : : getIntType ( ) : ( ctx - > FLOAT ( ) ? Type : : getFloatType ( ) : Type : : getVoidType ( ) ) ;
}
/*
* @brief: visit function define
* @details:
* funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt;
* funcFParams: funcFParam (COMMA funcFParam)*;
* funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?;
* entry -> next -> others -> exit
* entry: allocas, br
* next: retval, params, br
* other: blockStmt init block
* exit: load retval, ret
*/
std : : any SysYIRGenerator : : visitFuncDef ( SysYParser : : FuncDefContext * ctx ) {
auto funcName = ctx - > Ident ( ) - > getText ( ) ;
auto funcParams = ctx - > funcFParams ( ) - > funcFParam ( ) ;
Type * returnType = any_cast < Type * > ( ctx - > funcType ( ) - > accept ( this ) ) ;
vector < Type * > paramTypes ;
vector < string > paramNames ;
for ( auto funcParam : funcParams ) {
Type * paramType = any_cast < Type * > ( funcParam - > bType ( ) - > accept ( this ) ) ;
paramTypes . push_back ( paramType ) ;
paramNames . push_back ( funcParam - > Ident ( ) - > getText ( ) ) ;
}
auto funcType = FunctionType : : get ( returnType , paramTypes ) ;
auto function = module - > createFunction ( funcName , funcType ) ;
auto entry = function - > getEntryBlock ( ) ;
for ( size_t i = 0 ; i < paramTypes . size ( ) ; i + + )
entry - > createArgument ( paramTypes [ i ] , paramNames [ i ] ) ;
builder . setPosition ( entry , entry - > end ( ) ) ;
ctx - > blockStmt ( ) - > accept ( this ) ;
return function ;
}
/*
* @brief: visit blockStmt
* @details:
* blockStmt: LBRACE blockItem* RBRACE;
* blockItem: decl | stmt;
*/
std : : any SysYIRGenerator : : visitBlockStmt ( SysYParser : : BlockStmtContext * ctx ) {
SymbolTable : : BlockScope scope ( symbols_table ) ;
for ( auto item : ctx - > blockItem ( ) )
item - > accept ( this ) ;
builder . getBasicBlock ( ) ;
return std : : any ( ) ;
}
std : : any SysYIRGenerator : : visitFuncRParams ( SysYParser : : FuncRParamsContext * ctx ) {
return visitChildren ( ctx ) ;
}
std : : any SysYIRGenerator : : visitNumber ( SysYParser : : NumberContext * ctx ) {
return visitChildren ( ctx ) ;
}
std : : any SysYIRGenerator : : visitString ( SysYParser : : StringContext * ctx ) {
return visitChildren ( ctx ) ;
}
end
*/
} // namespace sysy