예제 #1
0
        public static void GenerateCode(ElseIfHeader header, GeneratorContext builder)
        {
            string currentEndLabel = builder.DeclareLabel("endElif");

            builder.AddCode(header.Condition);
            builder.AddOp(new JumpLabelConditionalNegated(currentEndLabel), header.IfToken);

            foreach (Expression statement in header.ParentBlockHint.Statements)
            {
                builder.AddCode(statement);
            }

            string finalEndLabel = header.EndLabelHint;

            if (finalEndLabel == null)
            {
                throw new Exception("Encountered ElseIf Header without an end label!");
            }

            if (header.NextConditionalComponentHint == null)
            {
                builder.SetLabelToNext(finalEndLabel);

                if (header.RequiresScopeHint)
                {
                    builder.AddOp(new ScopeEnd(), header.ParentBlockHint.EndToken);
                }
            }
            else
            {
                builder.AddOp(new JumpLabel(finalEndLabel));
            }

            builder.SetLabelToNext(currentEndLabel);
        }
예제 #2
0
파일: Variables.cs 프로젝트: Seti-0/NSprak
        public static void GenerateCode(VariableAssignment assignment, GeneratorContext builder)
        {
            if (assignment.IsDeclaration)
            {
                if (assignment.HasValue)
                {
                    builder.AddCode(assignment.Value);
                }

                else
                {
                    builder.AddOp(new LiteralValue(assignment.DeclarationType.Default()), assignment.TypeToken);
                }

                builder.AddOp(new VariableCreate(assignment.Name), assignment.NameToken);
            }
            else
            {
                if (assignment.Indices.Count > 1)
                {
                    throw new NotImplementedException("Only one level of indexing is supported at the moment");
                }

                if (assignment.BuiltInFunctionHint != null)
                {
                    if (assignment.Indices.Count == 0)
                    {
                        builder.AddOp(new VariableGet(assignment.Name), assignment.NameToken);
                    }
                    else
                    {
                        builder.AddOp(new VariableGet(assignment.Name));
                        builder.AddCode(assignment.Indices[0].Index);
                        builder.AddOp(new ArrayElementGet());
                    }
                }

                if (assignment.Value != null)
                {
                    builder.AddCode(assignment.Value);
                }

                if (assignment.BuiltInFunctionHint != null)
                {
                    builder.AddOp(new CallBuiltIn(assignment.BuiltInFunctionHint), assignment.OperatorToken);
                }

                if (assignment.Indices.Count == 0)
                {
                    builder.AddOp(new VariableSet(assignment.Name), assignment.NameToken);
                }
                else
                {
                    builder.AddCode(assignment.Indices[0].Index);
                    builder.AddOp(new ArrayElementSet(assignment.Name),
                                  assignment.NameToken);
                }
            }
        }
예제 #3
0
파일: Functions.cs 프로젝트: Seti-0/NSprak
        public static void GenerateCode(OperatorCall call, GeneratorContext builder)
        {
            if (call.LeftInput != null)
            {
                builder.AddCode(call.LeftInput);
            }
            if (call.RightInput != null)
            {
                builder.AddCode(call.RightInput);
            }

            builder.AddOp(new CallBuiltIn(call.BuiltInFunctionHint), call.OperatorToken);
        }
예제 #4
0
        public static void GenerateCode(Block block, GeneratorContext builder)
        {
            builder.AddComment("Begin " + block.Header.FriendlyBlockName);

            builder.AddCode(block.Header);

            builder.AddComment("End " + block.Header.FriendlyBlockName);
        }
예제 #5
0
        public static void GenerateCode(IfHeader header, GeneratorContext builder)
        {
            if (header.RequiresScopeHint)
            {
                builder.AddOp(new ScopeBegin(), header.IfToken);
            }

            string currentEndLabel = builder.DeclareLabel("endIf");

            string finalEndLabel = null;

            if (header.NextConditionalComponentHint != null)
            {
                finalEndLabel = builder.DeclareLabel("endConditional");
            }

            builder.AddCode(header.Condition);

            builder.AddOp(new JumpLabelConditionalNegated(currentEndLabel), header.IfToken);

            foreach (Expression statement in header.ParentBlockHint.Statements)
            {
                builder.AddCode(statement);
            }

            if (header.NextConditionalComponentHint != null)
            {
                IConditionalSubComponent current = header.NextConditionalComponentHint;
                while (current != null)
                {
                    current.EndLabelHint = finalEndLabel;
                    current = current.NextConditionalComponentHint;
                }

                builder.AddOp(new JumpLabel(finalEndLabel));
            }

            builder.SetLabelToNext(currentEndLabel);

            if (header.NextConditionalComponentHint == null &&
                header.RequiresScopeHint)
            {
                builder.AddOp(new ScopeEnd(), header.ParentBlockHint.EndToken);
            }
        }
예제 #6
0
        public static void GenerateCode(Expressions.Types.Return statement, GeneratorContext builder)
        {
            if (statement.HasValue)
            {
                builder.AddCode(statement.Value);
            }

            builder.AddOp(new Types.Return(), statement.ReturnToken);
        }
예제 #7
0
파일: Literals.cs 프로젝트: Seti-0/NSprak
        public static void GenerateCode(LiteralArrayGet literal, GeneratorContext builder)
        {
            foreach (Expression element in literal.Elements)
            {
                builder.AddCode(element);
            }

            builder.AddOp(new ArrayValue(literal.Elements.Count), literal.StartToken);
        }
예제 #8
0
파일: Functions.cs 프로젝트: Seti-0/NSprak
        public static void GenerateCode(FunctionHeader header, GeneratorContext builder)
        {
            foreach (string name in header.ParameterNames.Reverse())
            {
                builder.AddOp(new VariableCreate(name), header.NameToken);
            }

            foreach (Expression statement in header.ParentBlockHint.Statements)
            {
                builder.AddCode(statement);
            }

            // This is hacky, and might be cleaned up someday
            List <Op> sheet         = builder.Operations;
            bool      returnMissing = sheet.Count == 0 || !(sheet[^ 1] is Types.Return);
예제 #9
0
파일: Functions.cs 프로젝트: Seti-0/NSprak
        public static void GenerateCode(FunctionCall call, GeneratorContext builder)
        {
            foreach (Expression arg in call.Arguments)
            {
                builder.AddCode(arg);
            }

            if (call.BuiltInFunctionHint != null)
            {
                builder.AddOp(new CallBuiltIn(call.BuiltInFunctionHint), call.NameToken);
            }

            else
            {
                builder.AddOp(new Call(call.UserFunctionHint), call.NameToken);
            }
        }
예제 #10
0
        public static void GenerateCode(ElseHeader header, GeneratorContext builder)
        {
            foreach (Expression statement in header.ParentBlockHint.Statements)
            {
                builder.AddCode(statement);
            }

            string conditionalEndLabel = header.EndLabelHint;

            if (conditionalEndLabel == null)
            {
                throw new Exception("Encountered Else Header without an end label!");
            }

            builder.SetLabelToNext(conditionalEndLabel);

            if (header.RequiresScopeHint)
            {
                builder.AddOp(new ScopeEnd(), header.ParentBlockHint.EndToken);
            }
        }
예제 #11
0
파일: Variables.cs 프로젝트: Seti-0/NSprak
 public static void GenerateCode(Indexer indexer, GeneratorContext builder)
 {
     builder.AddCode(indexer.SourceExpression);
     builder.AddCode(indexer.IndexExpression);
     builder.AddOp(new ArrayElementGet(), indexer.OpeningBracket);
 }
예제 #12
0
        public static void GenerateCode(LoopHeader header, GeneratorContext builder)
        {
            bool requiresOuterScope = !header.IsInfinite;
            bool requiresInnerScope = header.RequiresScopeHint;

            if (requiresOuterScope)
            {
                builder.AddOp(new ScopeBegin(), header.LoopToken);
            }

            string endLabel = builder.DeclareLabel("LoopEnd");

            builder.BreakLabels.Push(endLabel);

            string continueLabel = builder.DeclareLabel("LoopContinue");

            builder.ContinueLabels.Push(continueLabel);

            string indexName = null;

            if (header.IsInfinite)
            {
                builder.SetLabelToNext(continueLabel);
            }

            else if (header.IsRange)
            {
                builder.PushIndex();
                indexName = header.Name;

                // For the end expression, don't use a variable if a literal could be used instead
                // Actually, it would be better if this were generalized to statements that translate to a single
                // op, but that is an optimization for another day.
                Op endOp;

                if (header.RangeEnd is LiteralGet end)
                {
                    endOp = new LiteralValue(end.Value);
                }

                else
                {
                    string endName = builder.GetIndexedName("end");
                    builder.AddCode(header.RangeEnd);
                    builder.AddOp(new VariableCreate(endName), header.LoopToken);

                    endOp = new VariableGet(endName);
                }

                builder.AddCode(header.RangeStart);
                builder.AddOp(new VariableCreate(indexName), header.NameToken);

                builder.SetLabelToNext(continueLabel);

                builder.AddOp(new VariableGet(indexName), header.NameToken);
                builder.AddOp(endOp);
                builder.AddOp(new GreaterThan(), header.FromToken);
                builder.AddOp(new JumpLabelConditional(endLabel), header.FromToken);
            }
            else
            {
                builder.PushIndex();
                indexName = builder.GetIndexedName("index");
                string arrayName   = builder.GetIndexedName("array");
                string countName   = builder.GetIndexedName("count");
                string currentName = header.Name ?? "@";

                builder.AddCode(header.Array);
                builder.AddOp(new VariableCreate(arrayName), header.LoopToken);

                builder.AddOp(new ArrayCount(arrayName), header.LoopToken);
                builder.AddOp(new VariableCreate(countName), header.LoopToken);

                builder.AddOp(new LiteralValue(new SprakNumber(0)), header.LoopToken);
                builder.AddOp(new VariableCreate(indexName), header.LoopToken);

                builder.AddOp(new LiteralValue(SprakUnit.Value), header.LoopToken);
                builder.AddOp(new VariableCreate(currentName), header.LoopToken);

                builder.SetLabelToNext(continueLabel);

                builder.AddOp(new VariableGet(indexName), header.LoopToken);
                builder.AddOp(new VariableGet(countName), header.LoopToken);
                builder.AddOp(new GreaterThanOrEqualTo(), header.LoopToken);
                builder.AddOp(new JumpLabelConditional(endLabel), header.LoopToken);

                builder.AddOp(new VariableGet(arrayName), header.InToken);
                builder.AddOp(new VariableGet(indexName), header.InToken);
                builder.AddOp(new ArrayElementGet(), header.InToken);
                builder.AddOp(new VariableSet(currentName), header.InToken);

                builder.AddOp(new Increment(indexName), header.InToken);
            };

            // This is used by the continue command, currently.
            header.IndexNameHint = indexName;

            if (requiresInnerScope)
            {
                builder.AddOp(new ScopeBegin(), header.LoopToken);
            }

            foreach (Expression statement in header.ParentBlockHint.Statements)
            {
                builder.AddCode(statement);
            }

            if (requiresInnerScope)
            {
                builder.AddOp(new ScopeEnd(), header.EndToken);
            }

            if (header.IsRange)
            {
                builder.AddOp(new Increment(indexName), header.EndToken);
            }

            builder.AddOp(new JumpLabel(continueLabel), header.EndToken);
            builder.SetLabelToNext(endLabel);

            if (!header.IsInfinite)
            {
                builder.PopIndex();
            }

            if (requiresOuterScope)
            {
                builder.AddOp(new ScopeEnd(), header.EndToken);
            }

            builder.BreakLabels.Pop();
            builder.ContinueLabels.Pop();
        }
예제 #13
0
파일: Literals.cs 프로젝트: Seti-0/NSprak
 public static void GenerateCode(Group group, GeneratorContext builder)
 {
     builder.AddCode(group.Value);
 }