/* simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp */ private AST.Expression ParseSimpleExpr() { AST.Expression expr = null; if (Stream.IsNumber()) { expr = new AST.NumberExpression(Stream.GetNumber().NumberValue.Value); Stream.MoveNext(); } else if (Stream.IsString()) { expr = new AST.StringExpression(Stream.GetString().Value); Stream.MoveNext(); } else if (Stream.IsKeyword("nil")) { expr = new AST.NilExpression(); Stream.MoveNext(); } else if (Stream.IsKeyword("true")) { expr = new AST.BoolExpression(true); Stream.MoveNext(); } else if (Stream.IsKeyword("false")) { expr = new AST.BoolExpression(false); Stream.MoveNext(); } else if (Stream.IsKeyword("...")) { expr = new AST.VarArgsExpression(); Stream.MoveNext(); } else if (Stream.IsKeyword("{")) { expr = ParseConstructor(); } else if (Stream.IsKeyword("function")) { Stream.MoveNext(); return new AST.FunctionExpression(ParseBody()); } else { expr = ParsePrimaryExpr(); } return expr; }
public void Visit(AST.ForStatement statement) { if (statement.Clause is AST.NumForClause) { AST.NumForClause clause = (AST.NumForClause)statement.Clause; AST.Expression exp1 = clause.Expr1; AST.Expression exp2 = clause.Expr2; AST.Expression exp3 = clause.Expr3; if (exp3 == null) { exp3 = new AST.NumberExpression(1); } CompilerState.SavedState save = State.SaveState(); // Initialize the variables for the loop. int valPosition = State.stackPosition; exp1.Visit(new ExpressionCompiler(State, 1)); int maxPosition = State.stackPosition; exp2.Visit(new ExpressionCompiler(State, 1)); int stepPosition = State.stackPosition; exp3.Visit(new ExpressionCompiler(State, 1)); // Verify that the variables are all numbers foreach (int position in new int[] { valPosition, maxPosition, stepPosition }) { State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETGLOBAL(State.AddConstant("tonumber"))); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - position)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeCALL(1)); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(1, true)); } String forCondLabel = State.getNewLabel(); State.bytecodes.Add(VirtualMachine.OpCodes.AND); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.AND); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.JMPTRUE); State.stackPosition--; State.jumps.Add(new KeyValuePair<string, int>(forCondLabel, State.bytecodes.Count - 1)); State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETGLOBAL(State.AddConstant("error"))); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeCALL(0)); State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(0, true)); State.stackPosition--; // Condition for the loop State.labels.Add(forCondLabel, State.bytecodes.Count); State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(0.0))); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - stepPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.LESS); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - valPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - maxPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.LESSEQ); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.AND); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - stepPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(0.0))); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.LESSEQ); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - maxPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - valPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.LESSEQ); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.AND); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.OR); State.stackPosition--; String bodyLabel = State.getNewLabel(); String afterLabel = State.getNewLabel(); State.bytecodes.Add(VirtualMachine.OpCodes.JMPTRUE); State.stackPosition--; State.jumps.Add(new KeyValuePair<string, int>(bodyLabel, State.bytecodes.Count - 1)); State.bytecodes.Add(VirtualMachine.OpCodes.JMP); State.jumps.Add(new KeyValuePair<string, int>(afterLabel, State.bytecodes.Count - 1)); // Body CompilerState.SavedState loopSave = State.SaveState(); String oldBreakLabel = State.currentBreakLabel; CompilerState.SavedState oldBreakState = State.currentBreakState; State.currentBreakLabel = afterLabel; State.currentBreakState = State.SaveState(); State.labels.Add(bodyLabel, State.bytecodes.Count); State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - valPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSEVAR(1)); State.newClosedVars[clause.Name] = State.closureStackPosition; State.closureStackPosition++; State.stackVars[clause.Name] = State.stackPosition - 1; ChunkCompiler chunk = new ChunkCompiler(statement.Block, State, loopSave, false); State.currentBreakLabel = oldBreakLabel; State.currentBreakState = oldBreakState; State.RestoreState(loopSave); // Increment value State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - valPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - stepPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.ADD); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - valPosition)); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.JMP); State.jumps.Add(new KeyValuePair<string, int>(forCondLabel, State.bytecodes.Count - 1)); State.labels.Add(afterLabel, State.bytecodes.Count); State.RestoreState(save); } else { AST.ListForClause clause = (AST.ListForClause)statement.Clause; CompilerState.SavedState forSave = State.SaveState(); int fPosition = State.stackPosition; int sPosition = State.stackPosition + 1; int vPosition = State.stackPosition + 2; CompileExpressionList(clause.Expressions, 3); String afterLabel = State.getNewLabel(); String startLabel = State.getNewLabel(); String bodyLabel = State.getNewLabel(); State.labels.Add(startLabel, State.bytecodes.Count); CompilerState.SavedState loopSave = State.SaveState(); State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - fPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - sPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - vPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakeCALL(2)); State.stackPosition -= 2; State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(clause.Names.Count, true)); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSEVAR(clause.Names.Count)); foreach (String name in clause.Names) { State.stackVars[name] = State.stackPosition; State.stackPosition++; State.newClosedVars[name] = State.closureStackPosition; State.closureStackPosition++; } State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(clause.Names.Count)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - vPosition)); State.stackPosition--; State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - vPosition)); State.stackPosition++; State.bytecodes.Add(VirtualMachine.OpCodes.JMPTRUE); State.stackPosition--; State.jumps.Add(new KeyValuePair<string, int>(bodyLabel, State.bytecodes.Count - 1)); State.Cleanup(loopSave); State.bytecodes.Add(VirtualMachine.OpCodes.JMP); State.jumps.Add(new KeyValuePair<string, int>(afterLabel, State.bytecodes.Count - 1)); State.labels[bodyLabel] = State.bytecodes.Count; String oldBreakLabel = State.currentBreakLabel; CompilerState.SavedState oldBreakState = State.currentBreakState; State.currentBreakLabel = afterLabel; State.currentBreakState = State.SaveState(); ChunkCompiler chunk = new ChunkCompiler(statement.Block, State, loopSave, false); State.currentBreakState = oldBreakState; State.currentBreakLabel = oldBreakLabel; State.RestoreState(loopSave); State.bytecodes.Add(VirtualMachine.OpCodes.JMP); State.jumps.Add(new KeyValuePair<string, int>(startLabel, State.bytecodes.Count - 1)); State.labels.Add(afterLabel, State.bytecodes.Count); State.RestoreState(forSave); } }