예제 #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 FunctionCompiler(CompilerState oldState, AST.Body body, bool selfFunction)
        {
            State = new CompilerState();

            State.initialClosureStackPosition = oldState.closureStackPosition;
            State.closureStackPosition = oldState.closureStackPosition;
            State.closedVars = oldState.closedVars;
            foreach (KeyValuePair<String, int> i in oldState.newClosedVars)
            {
                State.closedVars[i.Key] = i.Value;
            }

            State.stackPosition = 1;

            CompilerState.SavedState savedState = State.SaveState();

            List<String> paramList = body.ParamList.NamedParams;
            if (selfFunction)
            {
                List<String> pList = new List<String>();
                pList.Add("self");
                pList.AddRange(paramList);
                paramList = pList;
            }

            if (paramList.Count > 0)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(paramList.Count));
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSEVAR(paramList.Count));
                State.stackPosition += paramList.Count;
            }

            int stackIndex = 1;
            foreach (String param in paramList)
            {
                State.stackVars[param] = stackIndex;
                stackIndex++;

                State.newClosedVars[param] = State.closureStackPosition;
                State.closureStackPosition++;
            }

            if (body.ParamList.HasVarArgs)
            {
                State.stackVars["..."] = 0;
            }

            new ChunkCompiler(body.Chunk, State, savedState, true);
            State.ResolveJumps();

            Id = Guid.NewGuid().ToString();
        }
예제 #3
0
        public void Visit(AST.LocalAssignmentStatement statement)
        {
            int numVars = statement.Variables.Count;

            int initialStackPosition = State.stackPosition;
            CompileExpressionList(statement.Expressions, numVars);

            int initialClosureStackPosition = State.closureStackPosition;
            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSEVAR(statement.Variables.Count));
            State.closureStackPosition += statement.Variables.Count;

            for (int i = 0; i < statement.Variables.Count; i++)
            {
                State.stackVars[statement.Variables[i]] = initialStackPosition + i;
                State.newClosedVars[statement.Variables[i]] = initialClosureStackPosition + i;
            }
        }
예제 #4
0
 public void Visit(AST.NameExpression expression)
 {
     if (State.stackVars.ContainsKey(expression.Value))
     {
         State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - rightPosition)); State.stackPosition++;
         State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - State.stackVars[expression.Value])); State.stackPosition--;
     }
     else if (State.closedVars.ContainsKey(expression.Value))
     {
         State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - rightPosition)); State.stackPosition++;
         State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTUPVAL(State.initialClosureStackPosition - State.closedVars[expression.Value])); State.stackPosition--;
     }
     else
     {
         State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - rightPosition)); State.stackPosition++;
         State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTGLOBAL(State.AddConstant(expression.Value))); State.stackPosition--;
     }
 }
예제 #5
0
        public void Visit(AST.LocalFunctionStatement statement)
        {
            int funcStackPos = State.stackPosition;
            State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(null)));
            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSEVAR(1));
            State.stackVars[statement.Name] = State.stackPosition; State.stackPosition++;
            State.newClosedVars[statement.Name] = State.closureStackPosition; State.closureStackPosition++;

            FunctionCompiler funcCompiler = new FunctionCompiler(State, statement.Body, false);

            VirtualMachine.Function function = new VirtualMachine.Function(funcCompiler.State.bytecodes.ToArray(), funcCompiler.State.constants.ToArray(), Guid.NewGuid().ToString(),
                                                                           funcCompiler.State.childFunctions, funcCompiler.State.positions, statement.Name);
            State.childFunctions.Add(function);

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSURE(State.AddConstant(function.Id)));
            State.stackPosition++;

            State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - funcStackPos));
            State.stackPosition--;
        }
예제 #6
0
        public ChunkCompiler(AST.Chunk chunk, CompilerState state, CompilerState.SavedState save, bool returns)
        {
            State = state;

            savedState = save;
            if (save == null)
            {
                savedState = State.SaveState();
            }

            foreach (AST.Statement statement in chunk.Statements)
            {
                state.positions[state.bytecodes.Count] = statement.SourcePos;
                statement.Visit(this);
            }

            CleanupChunk();

            if (!hasReturned && returns)
            {
                state.bytecodes.Add(VirtualMachine.OpCodes.MakeRET(0));
            }
        }
예제 #7
0
        public void Visit(AST.Constructor expression)
        {
            int tablePosition = State.stackPosition;
            State.bytecodes.Add(VirtualMachine.OpCodes.NEWTABLE); State.stackPosition++;

            double listIndex = 1;

            foreach (AST.ConField field in expression.Fields)
            {
                if (field is AST.NameRecField)
                {
                    AST.NameRecField nField = (AST.NameRecField)field;

                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - tablePosition)); State.stackPosition++;
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(nField.Name))); State.stackPosition++;
                    nField.Value.Visit(this); // Stack position ++;
                    State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
                }
                else if (field is AST.ListField)
                {
                    AST.ListField lField = (AST.ListField)field;

                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - tablePosition)); State.stackPosition++;
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(listIndex++))); State.stackPosition++;
                    lField.Expr.Visit(new ExpressionCompiler(State, field == expression.Fields.Last() ? 0 : 1)); // Stack position ++;
                    State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
                }
                else if (field is AST.ExprRecField)
                {
                    AST.ExprRecField eField = (AST.ExprRecField)field;

                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - tablePosition)); State.stackPosition++;
                    eField.IndexExpr.Visit(this); // Stack position ++;
                    eField.Value.Visit(this); // Stack position ++;
                    State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
                }
            }
        }
예제 #8
0
        public void Visit(AST.FunctionStatement statement)
        {
            bool isSelfFunction = statement.SelfName != null;
            bool isGlobal = !isSelfFunction && statement.FieldNames.Count == 0;

            if (!isGlobal)
            {
                // Get the table
                AST.Expression expr = new AST.NameExpression(statement.MainName);

                if (statement.FieldNames.Count > 0)
                {
                    foreach (String field in statement.FieldNames.GetRange(0, statement.FieldNames.Count - 1))
                    {
                        expr = new AST.LookupExpression(expr, field);
                    }

                    if (isSelfFunction)
                    {
                        expr = new AST.LookupExpression(expr, statement.FieldNames.Last());
                    }
                }

                expr.Visit(new ExpressionCompiler(State, 1));

                // Get the key
                if (isSelfFunction)
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(statement.SelfName))); State.stackPosition++;
                }
                else
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(statement.FieldNames.Last()))); State.stackPosition++;
                }
            }

            FunctionCompiler funcCompiler = new FunctionCompiler(State, statement.Body, isSelfFunction);

            VirtualMachine.Function function = new VirtualMachine.Function(funcCompiler.State.bytecodes.ToArray(), funcCompiler.State.constants.ToArray(), Guid.NewGuid().ToString(),
                                                                           funcCompiler.State.childFunctions, funcCompiler.State.positions, statement.MainName);
            State.childFunctions.Add(function);

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSURE(State.AddConstant(function.Id))); State.stackPosition++;

            if (!isGlobal)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
            }
            else
            {
                if (State.stackVars.ContainsKey(statement.MainName))
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - State.stackVars[statement.MainName])); State.stackPosition--;
                }
                else
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTGLOBAL(State.AddConstant(statement.MainName))); State.stackPosition--;
                }
            }
        }
예제 #9
0
 public void Visit(AST.NilExpression expression)
 {
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(null)));
     State.stackPosition++;
 }
예제 #10
0
 public void Visit(AST.Constructor expression)
 {
     throw new NotImplementedException();
 }
예제 #11
0
 public void Visit(AST.IndexExpression expression)
 {
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - leftPosition)); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - (leftPosition + 1))); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - rightPosition)); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
 }
예제 #12
0
 public void Visit(AST.LookupExpression expression)
 {
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - leftPosition)); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(expression.Name))); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - rightPosition)); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
 }
예제 #13
0
 public void Visit(AST.FunctionCallStatement statement)
 {
     statement.Expr.Visit(new ExpressionCompiler(State, 0));
     State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(0, true));
     State.stackPosition--;
 }
예제 #14
0
 public void Visit(AST.DoStatement statement)
 {
     new ChunkCompiler(statement.Block, State, null, false);
 }
예제 #15
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);
            }
        }
예제 #16
0
        public void Visit(AST.UnOpExpression expression)
        {
            expression.Expr.Visit(this);

            if (expression.Op.Equals("not"))
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.NOT);
            }
            else if (expression.Op.Equals("-"))
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.NEG);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
예제 #17
0
 public void Visit(AST.ParenExpression expression)
 {
     expression.Expr.Visit(new ExpressionCompiler(State, 1));
 }
예제 #18
0
 public void Visit(AST.VarArgsExpression expression)
 {
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - State.stackVars["..."]));
     State.stackPosition++;
 }
예제 #19
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;
        }
예제 #20
0
        public void Visit(AST.AssignmentStatement statement)
        {
            int numVars = statement.Variables.Count;

            int startStackPosition = State.stackPosition;

            int[] leftStackPositions = new int[numVars];
            int[] rightStackPositions = new int[numVars];

            for (int i = 0; i < numVars; i++)
            {
                leftStackPositions[i] = State.stackPosition;
                statement.Variables[i].Visit(new LeftExpressionCompiler(State));
            }

            int initialStackPosition = State.stackPosition;
            for (int i = 0; i < statement.Expressions.Count; i++)
            {
                int numResults = 1;
                if (i == statement.Expressions.Count - 1)
                {
                    numResults = numVars - i;
                }

                int startPosition = State.stackPosition;
                statement.Expressions[i].Visit(new ExpressionCompiler(State, numResults));
                int endPosition = State.stackPosition;

                for (int j = 0; j < endPosition - startPosition && i + j < numVars; j++)
                {
                    rightStackPositions[i + j] = startPosition + j;
                }
            }

            int nowStackPosition = State.stackPosition;
            for (int i = 0; i < statement.Variables.Count - (nowStackPosition - initialStackPosition); i++)
            {
                rightStackPositions[(nowStackPosition - initialStackPosition) + i] = State.stackPosition;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(null)));
                State.stackPosition++;
            }

            for (int i = 0; i < numVars; i++)
            {
                statement.Variables[i].Visit(new AssignerExpressionCompiler(State, leftStackPositions[i], rightStackPositions[i]));
            }

            State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPSTACK(State.stackPosition - startStackPosition)); State.stackPosition = startStackPosition;
        }
예제 #21
0
        public void Visit(AST.FunctionApplicationExpression expression)
        {
            int funcIndex = State.stackPosition;

            if (expression.Obj is AST.SelfLookupExpression)
            {
                AST.SelfLookupExpression lookup = (AST.SelfLookupExpression)expression.Obj;
                int selfPos = State.stackPosition;
                lookup.Obj.Visit(new ExpressionCompiler(State, 1));
                int funcPos = State.stackPosition;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - selfPos)); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(lookup.Name))); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.GETTABLE); State.stackPosition--;

                State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - selfPos)); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - funcPos)); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - selfPos)); State.stackPosition--;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - funcPos)); State.stackPosition--;
            }
            else
            {
                expression.Obj.Visit(new ExpressionCompiler(State, 1));
            }

            foreach (AST.Expression expr in expression.Args)
            {
                ExpressionCompiler compiler = new ExpressionCompiler(State, 1);
                if (expr == expression.Args.Last())
                {
                    compiler = new ExpressionCompiler(State, 0);
                }

                expr.Visit(compiler);
            }

            int currentIndex = State.stackPosition;

            int argCount = expression.Args.Count;
            if (expression.Obj is AST.SelfLookupExpression)
            {
                argCount++;
            }

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCALL(argCount));

            if (NumResults > 0)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(NumResults, true));
                State.stackPosition = funcIndex + NumResults;
            }
            else
            {
                State.stackPosition = funcIndex + 1;
            }
        }
예제 #22
0
 public void Visit(AST.BinOpExpression expression)
 {
     throw new NotImplementedException();
 }
예제 #23
0
 public void Visit(AST.SelfLookupExpression expression)
 {
     throw new NotImplementedException();
 }
예제 #24
0
 public void Visit(AST.IndexExpression expression)
 {
     expression.Obj.Visit(new ExpressionCompiler(State, 1));
     expression.Index.Visit(new ExpressionCompiler(State, 1));
     State.bytecodes.Add(VirtualMachine.OpCodes.GETTABLE); State.stackPosition--;
 }
예제 #25
0
 public void Visit(AST.FunctionApplicationExpression expression)
 {
     throw new NotImplementedException();
 }
예제 #26
0
        public void Visit(AST.BreakStatement statement)
        {
            State.Cleanup(State.currentBreakState);

            State.bytecodes.Add(VirtualMachine.OpCodes.JMP);
            State.jumps.Add(new KeyValuePair<String, int>(State.currentBreakLabel, State.bytecodes.Count - 1));
        }
예제 #27
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;
        }
예제 #28
0
 public void Visit(AST.StringExpression expression)
 {
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(expression.Value)));
     State.stackPosition++;
 }
예제 #29
0
        public void Visit(AST.ReturnStatement statement)
        {
            foreach (AST.Expression expr in statement.Expressions)
            {
                ExpressionCompiler compiler = new ExpressionCompiler(State, 1);
                if (expr == statement.Expressions.Last())
                {
                    compiler = new ExpressionCompiler(State, 0);
                }

                expr.Visit(compiler);
            }

            if (State.newClosedVars.Count > 0)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPCLOSED(State.closureStackPosition - State.initialClosureStackPosition));
            }

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeRET(statement.Expressions.Count));

            hasReturned = true;
        }
예제 #30
0
 public void Visit(AST.LookupExpression expression)
 {
     expression.Obj.Visit(new ExpressionCompiler(State, 1));
     State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(expression.Name))); State.stackPosition++;
     State.bytecodes.Add(VirtualMachine.OpCodes.GETTABLE); State.stackPosition--;
 }