private void IfStmt(IfStmtNode node) { ScopeManager.ScopeEnter(); node.body = new StmtNode(); Move(); RequiredToken(Tag.DL_LPAR); node.condition = new ExprNode(); Expr(node.condition); if (node.condition.Type() != VarType.TYPE_BOOL) { new TypeMismatchError(VarType.TYPE_BOOL, node.condition.Type()).PrintErrMsg(); } RequiredToken(Tag.DL_RPAR); Stmt(node.body); ScopeManager.ScopeLeave(); if (TagIs(Tag.KW_ELSE)) { node.elseStmt = new ElseStmtNode(); ElseStmt(node.elseStmt); } }
public IfStmtNode(ExprNode Condition, SuiteNode Body, IfStmtNode ElseIf, SuiteNode Else) { this.Condition = Condition; this.Body = Body; this.ElseIf = ElseIf; this.Else = Else; }
public override ImperativeNode VisitIfStatementNode(IfStmtNode node) { var newIfExpr = node.IfExprNode.Accept(this); if (node.IfExprNode != newIfExpr) { node.IfExprNode = newIfExpr; } node.IfBody = VisitNodeList(node.IfBody); node.ElseIfList = VisitNodeList(node.ElseIfList.Cast <ImperativeNode>().ToList()).Cast <ElseIfBlock>().ToList(); node.ElseBody = VisitNodeList(node.ElseBody); return(node); }
void ifstmt(out Node node) { IfStmtNode ifStmtNode = new IfStmtNode(); NodeList body = null; Expect(19); Expect(8); expr(out node); ifStmtNode.IfExprNode = node; Expect(9); if (StartOf(2)) { Node singleStmt; stmt(out singleStmt); ifStmtNode.IfBody.Add(singleStmt); } else if (la.kind == 32) { Get(); stmtlist(out body); ifStmtNode.IfBody = body; Expect(33); } else { SynErr(54); } while (la.kind == 20) { ElseIfBlock elseifBlock = new ElseIfBlock(); Get(); Expect(8); expr(out node); elseifBlock.Expr = node; Expect(9); if (StartOf(2)) { Node singleStmt = null; stmt(out singleStmt); elseifBlock.Body.Add(singleStmt); } else if (la.kind == 32) { Get(); stmtlist(out body); elseifBlock.Body = body; Expect(33); } else { SynErr(55); } ifStmtNode.ElseIfList.Add(elseifBlock); } if (la.kind == 21) { Get(); if (StartOf(2)) { Node singleStmt = null; stmt(out singleStmt); ifStmtNode.ElseBody.Add(singleStmt); } else if (la.kind == 32) { Get(); stmtlist(out body); ifStmtNode.ElseBody = body; Expect(33); } else { SynErr(56); } } node = ifStmtNode; }
public virtual void VisitIfStatementNode(IfStmtNode node) { DefaultVisit(node); }
public virtual bool VisitIfStatementNode(IfStmtNode node) { return(DefaultVisit(node)); }
private void dfsTraverse(Node node) { if (node is TerminalNode) { TerminalNode t = node as TerminalNode; emit("push " + t.Value + ";\n"); FusionCore.DSASM.Operand op = buildOperand(t); emitPush(op); } else if (node is FunctionDefinitionNode) { FunctionDefinitionNode funcDef = node as FunctionDefinitionNode; // TODO jun: Add semantics for checking overloads (different parameter types) FusionCore.DSASM.FunctionNode fnode = new FusionCore.DSASM.FunctionNode(); fnode.name = funcDef.Name; fnode.paramCount = null == funcDef.Signature ? 0 : funcDef.Signature.Arguments.Count; fnode.pc = pc; fnode.localCount = funcDef.localVars; fnode.returntype = FusionCore.TypeSystem.getType(funcDef.ReturnType.Name); functionindex = functions.Append(fnode); // Append arg symbols if (fnode.paramCount > 0) { foreach (VarDeclNode argNode in funcDef.Signature.Arguments) { AllocateArg(argNode.NameNode.Value, functionindex, FusionCore.TypeSystem.getType(argNode.ArgumentType.Name)); } } // Traverse definition foreach (Node bnode in funcDef.FunctionBody.Body) { dfsTraverse(bnode); } // Append to the function group functiontable FusionCore.FunctionGroup funcGroup = new FusionCore.FunctionGroup(); // ArgList if (fnode.paramCount > 0) { List <FusionCore.Type> parameterTypes = new List <FusionCore.Type>(); foreach (VarDeclNode argNode in funcDef.Signature.Arguments) { parameterTypes.Add(FusionCore.TypeSystem.buildTypeObject(FusionCore.TypeSystem.getType(argNode.ArgumentType.Name), false)); } } // function return emit("ret" + FusionCore.DSASM.Constants.termline); emitReturn(); functionindex = (int)FusionCore.DSASM.Constants.kGlobalScope; argOffset = 0; baseOffset = 0; } else if (node is FunctionCallNode) { FunctionCallNode funcCall = node as FunctionCallNode; FusionCore.DSASM.FunctionNode fnode = new FusionCore.DSASM.FunctionNode(); fnode.name = funcCall.Function.Name; fnode.paramCount = funcCall.FormalArguments.Count; // Traverse the function args foreach (Node paramNode in funcCall.FormalArguments) { dfsTraverse(paramNode); } int fIndex = functions.getIndex(fnode); if ((int)FusionCore.DSASM.Constants.kInvalidIndex != fIndex) { emit("call " + fnode.name + FusionCore.DSASM.Constants.termline); emitCall(fIndex); if (FusionCore.PrimitiveType.kTypeVoid != functions.functionList[fIndex].returntype) { emit("push " + FusionCore.DSASM.kw.regRX + FusionCore.DSASM.Constants.termline); FusionCore.DSASM.Operand opRes; opRes.optype = FusionCore.DSASM.AddressType.Register; opRes.opdata = (int)FusionCore.DSASM.Registers.RX; emitPush(opRes); } } else { System.Console.WriteLine("Method '" + fnode.name + "' not found\n"); } } else if (node is IfStmtNode) { /* * * * def backpatch(bp, pc) * instr = instrstream[bp] * if instr.opcode is jmp * instr.op1 = pc * elseif instr.opcode is cjmp * instr.op2 = pc * end * end * * def backpatch(table, pc) * foreach node in table * backpatch(node.pc, pc) * end * end * */ /* * if(E) -> traverse E * bpTable = new instance * L1 = pc + 1 * L2 = null * bp = pc * emit(jmp, _cx, L1, L2) * { * S -> traverse S * L1 = null * bpTable.append(pc) * emit(jmp,labelEnd) * backpatch(bp,pc) * } * */ // TODO jun: Try to break up this emitter without while retaining theoretical meaning int bp = (int)FusionCore.DSASM.Constants.kInvalidIndex; int L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex; int L2 = (int)FusionCore.DSASM.Constants.kInvalidIndex; FusionCore.DSASM.Operand opCX; // If-expr IfStmtNode ifnode = node as IfStmtNode; dfsTraverse(ifnode.IfExprNode); emit("pop " + FusionCore.DSASM.kw.regCX + FusionCore.DSASM.Constants.termline); opCX.optype = FusionCore.DSASM.AddressType.Register; opCX.opdata = (int)FusionCore.DSASM.Registers.CX; emitPop(opCX); L1 = pc + 1; L2 = (int)FusionCore.DSASM.Constants.kInvalidIndex; bp = pc; emitCJmp(L1, L2); // If-body foreach (Node ifBody in ifnode.IfBody) { dfsTraverse(ifBody); } L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex; backpatchTable.append(pc, L1); emitJmp(L1); backpatch(bp, pc); /* * else if(E) -> traverse E * L1 = pc + 1 * L2 = null * bp = pc * emit(jmp, _cx, L1, L2) * { * S -> traverse S * L1 = null * bpTable.append(pc) * emit(jmp,labelEnd) * backpatch(bp,pc) * } * */ // Elseif-expr foreach (ElseIfBlock elseifNode in ifnode.ElseIfList) { dfsTraverse(elseifNode.Expr); emit("pop " + FusionCore.DSASM.kw.regCX + FusionCore.DSASM.Constants.termline); opCX.optype = FusionCore.DSASM.AddressType.Register; opCX.opdata = (int)FusionCore.DSASM.Registers.CX; emitPop(opCX); L1 = pc + 1; L2 = (int)FusionCore.DSASM.Constants.kInvalidIndex; bp = pc; emitCJmp(L1, L2); // Elseif-body if (null != elseifNode.Body) { foreach (Node elseifBody in elseifNode.Body) { dfsTraverse(elseifBody); } } L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex; backpatchTable.append(pc, L1); emitJmp(L1); backpatch(bp, pc); } /* * else * { * S -> traverse S * L1 = null * bpTable.append(pc) * emit(jmp,labelEnd) * backpatch(bp,pc) * } * */ // Else-body if (null != ifnode.ElseBody) { foreach (Node elseBody in ifnode.ElseBody) { dfsTraverse(elseBody); } L1 = (int)FusionCore.DSASM.Constants.kInvalidIndex; backpatchTable.append(pc, L1); emitJmp(L1); //backpatch(bp, pc); } /* * * -> backpatch(bpTable, pc) */ // ifstmt-exit backpatch(backpatchTable.backpatchList, pc); } else if (node is VarDeclNode) { VarDeclNode varNode = node as VarDeclNode; Allocate(varNode.NameNode.Value, functionindex, FusionCore.TypeSystem.getType(varNode.ArgumentType.Name)); } else if (node is BinaryExpressionNode) { BinaryExpressionNode b = node as BinaryExpressionNode; if (Operator.assign != b.Operator) { dfsTraverse(b.LeftNode); } dfsTraverse(b.RightNode); if (Operator.assign == b.Operator) { if (b.LeftNode is TerminalNode) { TerminalNode t = b.LeftNode as TerminalNode; bool isReturn = false; string s = t.Value; if (s == "return") { s = "_rx"; //isReturn = true; } // TODO jun: the emit string are only for console logging, // wrap them together with the actual emit function and flag them out as needed emit("pop " + s + FusionCore.DSASM.Constants.termline); FusionCore.DSASM.Operand op = buildOperand(t); emitPop(op); //if (isReturn) //{ // emit("ret" + FusionCore.DSASM.Constants.termline); // emitReturn(); // functionindex = (int)FusionCore.DSASM.Constants.kGlobalScope; //} } } else { emit("pop " + FusionCore.DSASM.kw.regBX + FusionCore.DSASM.Constants.termline); FusionCore.DSASM.Operand opBX; opBX.optype = FusionCore.DSASM.AddressType.Register; opBX.opdata = (int)FusionCore.DSASM.Registers.BX; emitPop(opBX); emit("pop " + FusionCore.DSASM.kw.regAX + FusionCore.DSASM.Constants.termline); FusionCore.DSASM.Operand opAX; opAX.optype = FusionCore.DSASM.AddressType.Register; opAX.opdata = (int)FusionCore.DSASM.Registers.AX; emitPop(opAX); string op = getOperator(b.Operator); emit(op + " " + FusionCore.DSASM.kw.regAX + ", " + FusionCore.DSASM.kw.regBX + FusionCore.DSASM.Constants.termline); emitBinary(getOpCode(b.Operator), opAX, opBX); emit("push " + FusionCore.DSASM.kw.regAX + FusionCore.DSASM.Constants.termline); FusionCore.DSASM.Operand opRes; opRes.optype = FusionCore.DSASM.AddressType.Register; opRes.opdata = (int)FusionCore.DSASM.Registers.AX; emitPush(opRes); } } }