public StringOffsetStart(JmpTarget target) { bytecode = new byte[3]; // string offsets always use 2-byte offset. bytecode[0] = 0x87; // PUSH#.B this.target = target; }
public override void MakeByteCode(ArrayList bytecodeList) { bytecodeList.Add(new SourceReference(this.Token, this.EndLineNumber)); ++SymbolTable.caseNesting; JmpTarget offsetTarget = new JmpTarget(); bytecodeList.Add(new OffsetStart(offsetTarget)); caseExpr.MakeByteCode(true, bytecodeList); JmpTarget[] targets = new JmpTarget[matchExprListList.Count]; for (int i = 0; i < matchExprListList.Count; ++i) { targets[i] = new JmpTarget(); // lay down all the match expressions for case i ArrayList matchExprList = matchExprListList[i] as ArrayList; foreach (object o in matchExprList) { if (o is Expr) { (o as Expr).MakeByteCode(true, bytecodeList); bytecodeList.Add(new JmpStart(0x0d, targets[i])); // CASE } else { PairOfExpr p = (PairOfExpr)o; p.left.MakeByteCode(true, bytecodeList); p.right.MakeByteCode(true, bytecodeList); bytecodeList.Add(new JmpStart(0x0e, targets[i])); // CASER } } } // Ensure that "OTHER:" gets listed in the case where there are no OTHER statements if (otherStmtList.Count == 0) { bytecodeList.Add(new SourceReference((SimpleToken)matchTokenList[matchTokenList.Count - 1], (int)matchEndLineNumberList[matchEndLineNumberList.Count - 1])); } foreach (Stmt s in otherStmtList) { s.MakeByteCode(bytecodeList); } bytecodeList.Add((byte)0x0c); // GOTO[] // Now some hackery to make sure that the "OTHER:" is // listed along with the first statement. if (otherStmtList.Count > 0) { Stmt firstStmt = (Stmt)otherStmtList[0]; firstStmt.Token.LineNumber = ((SimpleToken)matchTokenList[matchTokenList.Count - 1]).LineNumber; } for (int i = 0; i < matchExprListList.Count; ++i) { bytecodeList.Add(targets[i]); ArrayList matchStmtList = matchStmtListList[i] as ArrayList; // Ensure that the match expression(s) gets listed in the case where there are // no match statements if (matchStmtList.Count == 0) { bytecodeList.Add(new SourceReference((SimpleToken)matchTokenList[i], (int)matchEndLineNumberList[i])); } foreach (Stmt s in matchStmtList) { s.MakeByteCode(bytecodeList); } bytecodeList.Add((byte)0x0c); // GOTO[] // Now some hackery to make sure that the match expression(s) is // listed along with the first statement. if (matchStmtList.Count > 0) { Stmt firstStmt = (Stmt)matchStmtList[0]; firstStmt.Token.LineNumber = ((SimpleToken)matchTokenList[i]).LineNumber; } } bytecodeList.Add(offsetTarget); --SymbolTable.caseNesting; }
public override void MakeByteCode(ArrayList bytecodeList) { JmpTarget saveNextJmpTarget = SymbolTable.nextJmpTarget; JmpTarget saveQuitJmpTarget = SymbolTable.quitJmpTarget; JmpTarget nextJmpTarget = SymbolTable.nextJmpTarget = new JmpTarget(); JmpTarget quitJmpTarget = SymbolTable.quitJmpTarget = new JmpTarget(); int saveCaseNesting = SymbolTable.caseNesting; SymbolTable.caseNesting = 0; bytecodeList.Add(new SourceReference(this.Token, this.EndLineNumber)); if (type == RepeatType.Plain) // REPEAT { SymbolTable.insidePlainRepeat = true; bytecodeList.Add(nextJmpTarget); foreach (Stmt s in statementsList) { s.MakeByteCode(bytecodeList); } JmpStart jmpUp = new JmpStart(0x04, nextJmpTarget); // GOTO bytecodeList.Add(jmpUp); bytecodeList.Add(quitJmpTarget); } else if (type == RepeatType.NTimes) // REPEAT n { SymbolTable.insidePlainRepeat = false; repeatExpr.MakeByteCode(true, bytecodeList); JmpStart jmpDown = new JmpStart(0x08, quitJmpTarget); // LOOPJPF bytecodeList.Add(jmpDown); JmpTarget repeatJmpTarget = new JmpTarget(); bytecodeList.Add(repeatJmpTarget); foreach (Stmt s in statementsList) { s.MakeByteCode(bytecodeList); } bytecodeList.Add(nextJmpTarget); JmpStart jmpUp = new JmpStart(0x09, repeatJmpTarget); // LOOPRPT bytecodeList.Add(jmpUp); bytecodeList.Add(quitJmpTarget); } else if (type == RepeatType.WhileLoop) // REPEAT WHILE/UNTIL <cond> <stmts> { SymbolTable.insidePlainRepeat = true; bytecodeList.Add(nextJmpTarget); repeatExpr.MakeByteCode(true, bytecodeList); byte opcode = whileNotUntil ? (byte)0x0a : (byte)0x0b; // JPF | JPT JmpStart jmpDown = new JmpStart(opcode, quitJmpTarget); bytecodeList.Add(jmpDown); foreach (Stmt s in statementsList) { s.MakeByteCode(bytecodeList); } JmpStart jmpUp = new JmpStart(0x04, nextJmpTarget); // GOTO bytecodeList.Add(jmpUp); bytecodeList.Add(quitJmpTarget); } else // REPEAT <stmts> WHILE/UNTIL <cond> { JmpTarget topTarget = new JmpTarget(); bytecodeList.Add(topTarget); foreach (Stmt s in statementsList) { s.MakeByteCode(bytecodeList); } bytecodeList.Add(nextJmpTarget); repeatExpr.MakeByteCode(true, bytecodeList); byte opcode = whileNotUntil ? (byte)0x0b : (byte)0x0a; // JPT | JPF JmpStart jmpUp = new JmpStart(opcode, topTarget); bytecodeList.Add(jmpUp); bytecodeList.Add(quitJmpTarget); } SymbolTable.caseNesting = saveCaseNesting; SymbolTable.nextJmpTarget = saveNextJmpTarget; SymbolTable.quitJmpTarget = saveQuitJmpTarget; }
public override void MakeByteCode(bool leaveOnStack, ArrayList bytecodeList) { if (!leaveOnStack) throw new ParseException("StringExpr.MakeByteCode(false)", Token); JmpTarget stringTarget = new JmpTarget(); StringOffsetStart start = new StringOffsetStart(stringTarget); bytecodeList.Add(start); SymbolTable.StringList.Add(st.Text); SymbolTable.StringTargetList.Add(stringTarget); }
public override void MakeByteCode(ArrayList bytecodeList) { SymbolTable.insidePlainRepeat = true; JmpTarget saveNextJmpTarget = SymbolTable.nextJmpTarget; JmpTarget saveQuitJmpTarget = SymbolTable.quitJmpTarget; JmpTarget nextJmpTarget = SymbolTable.nextJmpTarget = new JmpTarget(); JmpTarget quitJmpTarget = SymbolTable.quitJmpTarget = new JmpTarget(); JmpTarget topJmpTarget = new JmpTarget(); int saveCaseNesting = SymbolTable.caseNesting; SymbolTable.caseNesting = 0; bytecodeList.Add(new SourceReference(this.Token, this.EndLineNumber)); fromExpr.MakeByteCode(true, bytecodeList); varExpr.MakeByteCode(Expr.StackOp.POP, bytecodeList); bytecodeList.Add(topJmpTarget); foreach (Stmt s in statementsList) { s.MakeByteCode(bytecodeList); } bytecodeList.Add(nextJmpTarget); byte opcode = 0x02; if (stepExpr != null) { stepExpr.MakeByteCode(true, bytecodeList); opcode = 0x06; } fromExpr.MakeByteCode(true, bytecodeList); toExpr.MakeByteCode(true, bytecodeList); varExpr.MakeByteCode(Expr.StackOp.USING, bytecodeList); bytecodeList.Add(new JmpStart(opcode, topJmpTarget)); bytecodeList.Add(quitJmpTarget); SymbolTable.caseNesting = saveCaseNesting; SymbolTable.nextJmpTarget = saveNextJmpTarget; SymbolTable.quitJmpTarget = saveQuitJmpTarget; }
public OffsetStart(JmpTarget target) { bytecode = new byte[2]; // assume it's a PUSH#k1 (1 byte offset) to start with. this.target = target; }
public override void MakeByteCode(bool leaveOnStack, ArrayList bytecodeList) { if (!leaveOnStack) throw new ParseException("LookExpr.MakeByteCode(false)", Token); if (look.EndsWith("Z")) { bytecodeList.Add((byte)0x35); // PUSH#0 } else { bytecodeList.Add((byte)0x36); // PUSH#1 } JmpTarget offsetTarget = new JmpTarget(); bytecodeList.Add(new OffsetStart(offsetTarget)); expr.MakeByteCode(true, bytecodeList); byte op, opr; if (look[4] == 'U') { op = 0x10; // LOOKUP opr = 0x12; // LOOKUPR } else { op = 0x11; // LOOKDN opr = 0x13; // LOOKDNR } foreach (object o in args) { if (o is Expr) { (o as Expr).MakeByteCode(true, bytecodeList); bytecodeList.Add(op); } else { PairOfExpr p = (PairOfExpr)o; p.left.MakeByteCode(true, bytecodeList); p.right.MakeByteCode(true, bytecodeList); bytecodeList.Add(opr); } } bytecodeList.Add((byte)0x0f); // LOOKEND bytecodeList.Add(offsetTarget); }
public JmpStart(byte opcode, JmpTarget target) { bytecode = new byte[2]; // assume it's a short branch (1 byte offset) to start with. bytecode[0] = opcode; this.target = target; }
public override void MakeByteCode(ArrayList bytecodeList) { bytecodeList.Add(new SourceReference(this.Token, this.EndLineNumber)); condExpr.MakeByteCode(true, bytecodeList); byte jmpOpcode = Token.Text.ToUpper().EndsWith("NOT") ? (byte)0x0b : (byte)0x0a; // JPT/JPF JmpTarget ifTarget = new JmpTarget(); JmpStart ifJmp = new JmpStart(jmpOpcode, ifTarget); bytecodeList.Add(ifJmp); foreach (Stmt s in ifStatementsList) { s.MakeByteCode(bytecodeList); } if (elseStatementsList == null) { bytecodeList.Add(ifTarget); } else { if (this.elseToken != null) bytecodeList.Add(new SourceReference(this.elseToken, this.elseEndLineNumber)); JmpTarget elseTarget = new JmpTarget(); JmpStart elseJmp = new JmpStart((byte)0x04, elseTarget); // GOTO bytecodeList.Add(elseJmp); bytecodeList.Add(ifTarget); foreach (Stmt s in elseStatementsList) { s.MakeByteCode(bytecodeList); } bytecodeList.Add(elseTarget); } }