示例#1
0
文件: Compiler.cs 项目: stroan/Lamn
 public VirtualMachine.Function CompileAST(AST ast)
 {
     ChunkCompiler chunkCompiler = new ChunkCompiler(ast.Contents, new CompilerState(), null, true);
     chunkCompiler.State.ResolveJumps();
     return new VirtualMachine.Function(chunkCompiler.State.bytecodes.ToArray(), chunkCompiler.State.constants.ToArray(), Guid.NewGuid().ToString(),
                                        chunkCompiler.State.childFunctions, chunkCompiler.State.positions, "root");
 }
示例#2
0
        public void Visit(AST.RepeatStatement statement)
        {
            String afterLabel = State.getNewLabel();
            String startLabel = State.getNewLabel();

            String oldBreakLabel = State.currentBreakLabel;
            CompilerState.SavedState oldBreakState = State.currentBreakState;

            State.currentBreakLabel = afterLabel;
            State.currentBreakState = State.SaveState();

            State.labels[startLabel] = State.bytecodes.Count;
            ChunkCompiler chunk = new ChunkCompiler(statement.Block, State, null, false);

            State.currentBreakLabel = oldBreakLabel;
            State.currentBreakState = oldBreakState;

            statement.Condition.Visit(new ExpressionCompiler(State, 1));
            State.bytecodes.Add(VirtualMachine.OpCodes.NOT);

            State.bytecodes.Add(VirtualMachine.OpCodes.JMPTRUE);
            State.stackPosition--;
            State.jumps.Add(new KeyValuePair<string, int>(startLabel, State.bytecodes.Count - 1));

            State.labels[afterLabel] = State.bytecodes.Count;
        }
示例#3
0
        public void Visit(AST.IfStatement statement)
        {
            String afterLabel = State.getNewLabel();

            KeyValuePair<String, AST.TestBlock>[] branchLabels = new KeyValuePair<String, AST.TestBlock>[statement.Conditions.Count];
            for (int i = 0; i < branchLabels.Length; i++)
            {
                branchLabels[i] = new KeyValuePair<string, AST.TestBlock>(State.getNewLabel(), statement.Conditions[i]);
            }

            for (int i = 0; i < branchLabels.Length; i++)
            {
                AST.TestBlock branch = branchLabels[i].Value;
                String branchLabel = branchLabels[i].Key;
                String startLabel = State.getNewLabel();

                State.labels[branchLabel] = State.bytecodes.Count;
                branch.Cond.Visit(new ExpressionCompiler(State, 1));

                State.bytecodes.Add(VirtualMachine.OpCodes.JMPTRUE);
                State.stackPosition--;
                State.jumps.Add(new KeyValuePair<string, int>(startLabel, State.bytecodes.Count - 1));

                State.bytecodes.Add(VirtualMachine.OpCodes.JMP);
                if (i < branchLabels.Length - 1)
                {
                    State.jumps.Add(new KeyValuePair<string, int>(branchLabels[i + 1].Key, State.bytecodes.Count - 1));
                }
                else
                {
                    State.jumps.Add(new KeyValuePair<string, int>(afterLabel, State.bytecodes.Count - 1));
                }

                State.labels[startLabel] = State.bytecodes.Count;
                ChunkCompiler chunk = new ChunkCompiler(branch.Block, State, null, false);

                if (i < branchLabels.Length - 1)
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.JMP);
                    State.jumps.Add(new KeyValuePair<string, int>(afterLabel, State.bytecodes.Count - 1));
                }
            }

            State.labels[afterLabel] = State.bytecodes.Count;
        }
示例#4
0
        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);
            }
        }