public Type Visit(Argument argument, FunctionGeneratorEnvironment arg) { arg.AllocateVariable(argument.id, (Type)argument.type); Program.Emit(T42Instruction.DECL(1)); return((Type)argument.type); }
public Type Visit(RegularStatement regularStatement, FunctionGeneratorEnvironment arg) { regularStatement.expr.Accept(this, arg); Program.Emit(T42Instruction.POP(1)); return(null); }
public Type Visit(BoolStatement boolStatement, FunctionGeneratorEnvironment arg) { var val = (boolStatement.value == true) ? 1 : 0; Program.Emit(T42Instruction.PUSHBOOL(val)); return(new BoolType()); }
public void Emit(T42Instruction inst) { if (inst.opcode == T42Instruction.OPCODE.LABEL) { AddressMap[inst.target] = Instructions.Count; } Instructions.Add(inst); }
public T42Program Generate(Statement stmt) { var globalEnvironment = new FunctionGeneratorEnvironment(); Program.Emit(T42Instruction.DECL(1)); Program.Emit(T42Instruction.BSR("main")); Program.Emit(T42Instruction.END); stmt.Accept(this, globalEnvironment); Program.Link(); return(Program); }
public Type Visit(IfStatement ifStatement, FunctionGeneratorEnvironment arg) { var labelno_end = arg.GetNextLabelNumber(); var end = $"{arg.FunctionName}_LABEL{labelno_end}"; ifStatement.expr.Accept(this, arg); Program.Emit(T42Instruction.BRF(end)); ifStatement.stmt.Accept(this, arg); Program.Emit(T42Instruction.LABEL(end)); return(null); }
public Type Visit(AssignStatement assignStatement, FunctionGeneratorEnvironment arg) { var type = arg.GetIdentifierType(assignStatement.id); var offset = arg.GetIdentifierOffset(assignStatement.id); Program.Emit(T42Instruction.LVAL(offset)); assignStatement.s.Accept(this, arg); if (type.GetType() == typeof(IntType)) { Program.Emit(T42Instruction.ASSINT); Program.Emit(T42Instruction.RVALINT(offset)); } else { Program.Emit(T42Instruction.ASSBOOL); Program.Emit(T42Instruction.RVALBOOL(offset)); } return(type); }
public Type Visit(IdentifierStatement identifierStatement, FunctionGeneratorEnvironment arg) { if (identifierStatement.list == null) { var type = arg.GetIdentifierType(identifierStatement.id); var offset = arg.GetIdentifierOffset(identifierStatement.id); if (type.GetType() == typeof(IntType)) { Program.Emit(T42Instruction.RVALINT(offset)); return(new IntType()); } else { Program.Emit(T42Instruction.RVALBOOL(offset)); return(new BoolType()); } } else { // CALL STATEMENT return(new BoolType()); } }
public Type Visit(NumStatement numStatement, FunctionGeneratorEnvironment arg) { Program.Emit(T42Instruction.PUSHINT(numStatement.num)); return(new IntType()); }
public Type Visit(BinOperatorStatement binOperatorStatement, FunctionGeneratorEnvironment arg) { var left = binOperatorStatement.left; var right = binOperatorStatement.right; var type = binOperatorStatement.type; var opType = MapOpExpr[binOperatorStatement.type]; switch (opType) { case OperatorExpression.INTEGER: left.Accept(this, arg); right.Accept(this, arg); switch (type) { case BinOperatorStatement.Type.ADD: Program.Emit(T42Instruction.ADD); break; case BinOperatorStatement.Type.SUB: Program.Emit(T42Instruction.SUB); break; case BinOperatorStatement.Type.MUL: Program.Emit(T42Instruction.MUL); break; case BinOperatorStatement.Type.DIV: Program.Emit(T42Instruction.DIV); break; } break; case OperatorExpression.LOGICAL: var labelno_next = arg.GetNextLabelNumber(); var labelno_end = arg.GetNextLabelNumber(); var end = $"{arg.FunctionName}_LABEL{labelno_end}"; var next = $"{arg.FunctionName}_LABEL{labelno_next}"; switch (binOperatorStatement.type) { case BinOperatorStatement.Type.OR: left.Accept(this, arg); Program.Emit(T42Instruction.BRF(next)); Program.Emit(T42Instruction.PUSHBOOL(1)); Program.Emit(T42Instruction.BRA(end)); Program.Emit(T42Instruction.LABEL(next)); right.Accept(this, arg); Program.Emit(T42Instruction.LABEL(end)); break; case BinOperatorStatement.Type.AND: left.Accept(this, arg); Program.Emit(T42Instruction.BRF(next)); right.Accept(this, arg); Program.Emit(T42Instruction.BRA(end)); Program.Emit(T42Instruction.LABEL(next)); Program.Emit(T42Instruction.PUSHBOOL(0)); Program.Emit(T42Instruction.LABEL(end)); break; } break; case OperatorExpression.INEQUALITY: left.Accept(this, arg); right.Accept(this, arg); switch (type) { case BinOperatorStatement.Type.LE: case BinOperatorStatement.Type.GEQ: Program.Emit(T42Instruction.LTINT); if (type == BinOperatorStatement.Type.GEQ) { Program.Emit(T42Instruction.NOT); } break; case BinOperatorStatement.Type.GR: case BinOperatorStatement.Type.LEQ: Program.Emit(T42Instruction.GTINT); if (type == BinOperatorStatement.Type.LEQ) { Program.Emit(T42Instruction.NOT); } break; } break; case OperatorExpression.EQUALITY: var t = left.Accept(this, arg); right.Accept(this, arg); if (t.GetType() == typeof(IntType)) { Program.Emit(T42Instruction.EQINT); } else { Program.Emit(T42Instruction.EQBOOL); } if (type == BinOperatorStatement.Type.NEQ) { Program.Emit(T42Instruction.NOT); } break; default: throw new Exception(); } return(new BoolType()); }