Exemplo n.º 1
0
        /// <summary>
        /// This method checks what type the parameters of a function is
        /// </summary>
        /// <param name="functionsParam">Is a variable, either float, bool, int or string</param>
        /// <param name="function">Is the function the parameter is given to</param>
        /// <returns></returns>
        private string findFuncInputparam(VarNode functionsParam, FuncNode function)
        {
            VarNode param = function.FunctionParameters.Find(x => x.Id == functionsParam.Id);

            if (param.SymbolType.IsFloat)
            {
                return("float ");
            }
            else if (param.SymbolType.Type == TokenType.BOOL)
            {
                return("bool ");
            }
            else if (!param.SymbolType.IsFloat)
            {
                return("int ");
            }
            else if (param.SymbolType.Type == TokenType.STRING)
            {
                return("String ");
            }
            else
            {
                new InvalidCodeException($"The function{function.Name} input parameter {functionsParam.Id} at {functionsParam.Line}:{functionsParam.Offset} is not used.");
                return("");
            }
        }
Exemplo n.º 2
0
        private LuaFunction FindFunc(FuncNode curNode, string index)
        {
            string[] indexes = index.Split(',');

            int linedefined = int.Parse(indexes[0]);
            int lastline    = int.Parse(indexes[1]);

            LuaFunction function = null;

            if (curNode.Function.Header.LineDefined == linedefined && curNode.Function.Header.LastLineDefined == lastline)
            {
                function = curNode.Function;
            }
            else
            {
                foreach (var cur in curNode.Children)
                {
                    if ((function = FindFunc(cur, index)) != null)
                    {
                        break;
                    }
                }
            }

            return(function);
        }
Exemplo n.º 3
0
 /// <summary>
 /// This method type checks the FuncNode node in the AST.
 /// </summary>
 /// <param name="funcNode">The node to check.</param>
 /// <returns>Returns null</returns>
 public override object Visit(FuncNode funcNode)
 {
     CurrentScope = GlobalScope.FindChild($"func_{funcNode.Name.Id}_{funcNode.Line}");
     funcNode.Statements.ForEach(stmnt =>
     {
         if (stmnt is CallNode)
         {
             if (((CallNode)stmnt).Id.Id == funcNode.Name.Id)
             {
                 new InvalidOperationException($"Illegal recursion at {stmnt.Line}:{stmnt.Offset}");
             }
         }
         stmnt.Accept(this);
     });
     if (funcNode.Statements.Any() && funcNode.Statements.Last().Type == TokenType.RETURN)
     {
         {
             funcNode.SymbolType = (TypeContext)funcNode.Statements.Last().Accept(this);
             CurrentScope        = CurrentScope.Parent ?? GlobalScope;
             return(funcNode.SymbolType);
         }
     }
     CurrentScope = CurrentScope.Parent ?? GlobalScope;
     return(null);
 }
Exemplo n.º 4
0
        void LoadFunctions()
        {
            FunctionTree = new FuncNode();
            LoadFunction(ref FunctionTree);

            FunctionTree = FunctionTree.Children[0];
        }
Exemplo n.º 5
0
        public void Accept(FuncNode node)
        {
            int preFuncLocals = table.CurrentOffset;

            table.PushScope();

            append(".{0}", node.Name);
            append("pop c");
            append("subi {0}, {1}", BP, preFuncLocals);

            for (int i = 0; i < node.Parameters.Count; i++)
            {
                table.AddSymbol(node.Parameters[i].Variable, DataType.GetSizeByType(node.Parameters[i].SourceLocation, node.Parameters[i].Type));
                storeLocal(node.Parameters[i].SourceLocation, node.Parameters[i].Variable, "b");
            }

            append("push c");

            append("addi {0}, {1}", BP, preFuncLocals);
            append("push {0}", BP);
            append("subi {0}, {1}", BP, preFuncLocals);

            node.VisitChildren(this);
            table.PopScope();

            append("pop {0}", BP);
            append("reti 0");
        }
Exemplo n.º 6
0
        private static void Main()
        {
            var startNode = new FuncNode <string, FileInfo>(x =>
            {
                var dir   = new DirectoryInfo(x);
                var files = dir.EnumerateFiles("*.txt").ToArray();

                if (files.Length > 0)
                {
                    var fileInfo   = files[0];
                    string dirName = Path.Combine(fileInfo.DirectoryName, "mr");
                    if (!Directory.Exists(dirName))
                    {
                        Directory.CreateDirectory(dirName);
                    }
                }

                return(files);
            });

            startNode.SetInput("..\\..\\..\\docs");

            startNode
            .CollectAllOutputsToOneArray()
            .ForArray(new SplitFilesIntoChunks())
            .ForEachOutput(new InitTermCount())
            .ForEachOutput(new SortTokens())
            .ForEachOutput(new ReduceToUniqueTokens())
            .CollectAllOutputsToOneArray()
            .ForArray(new MergeSort())
            .ForEachOutput(new ReduceToUniqueTokens2())
            .Process();
        }
Exemplo n.º 7
0
        private bool SetFunc(FuncNode curNode, LuaFunction function, string index)
        {
            string[] indexes = index.Split(',');

            int linedefined = int.Parse(indexes[0]);
            int lastline    = int.Parse(indexes[1]);

            if (curNode.Function.Header.LineDefined == linedefined && curNode.Function.Header.LastLineDefined == lastline)
            {
                curNode.Function = function;

                return(true);
            }
            else
            {
                foreach (var cur in curNode.Children)
                {
                    if (SetFunc(cur, function, index) != false)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemplo n.º 8
0
        /// <summary>
        /// This method will update function parameters of an enclosing function
        /// </summary>
        /// <param name="node">The node to look for</param>
        /// <param name="rhs">The typecontext to assign the variable</param>
        /// <param name="scopeName">The name of the calling scope</param>
        public void UpdateFuncVar(VarNode node, TypeContext rhs, string scopeName)
        {
            SymbolTableObject symobj = SymbolTableBuilder.GlobalSymbolTable.Children.First(symtab => symtab.Name == scopeName);

            FuncNode func = SymbolTableObject.FunctionDefinitions.First(fn => this.Name.Contains(fn.Name.Id) && this.Name.Contains("_" + fn.Line));

            if (func.FunctionParameters.Any(vn => vn.Id == node.Id))
            {
                node.Declaration = false;
            }
            symobj.UpdateTypedef(node, rhs, scopeName, false);
        }
Exemplo n.º 9
0
        private List <LuaFunction> GetFunc(FuncNode curNode)
        {
            List <LuaFunction> functions = new List <LuaFunction>();

            functions.Add(curNode.Function);

            foreach (var cur in curNode.Children)
            {
                functions.AddRange(GetFunc(cur));
            }

            return(functions);
        }
Exemplo n.º 10
0
        public async Task Can_Run_Func_Node_On_Inherited_Type()
        {
            var node = new FuncNode <TestObjectA>();

            node.AddShouldExecute(context => Task.FromResult(context.Subject.TestValueInt == 0));
            node.ExecutedFunc = context => { context.Subject.TestValueString = "Completed"; return(Task.FromResult(NodeResultStatus.Succeeded)); };

            var        testObject = new TestObjectASub();
            NodeResult result     = await node.ExecuteAsync(testObject);

            node.Status.Should().Be(NodeRunStatus.Completed);
            result.Status.Should().Be(NodeResultStatus.Succeeded);
            result.GetSubjectAs <TestObjectA>().TestValueString.Should().Be("Completed");
        }
        public async Task Node_With_ShouldExecuteBlock_Should_Run()
        {
            var node = new FuncNode <TestObjectA>();

            node.AddShouldExecuteBlock(new ShouldExecuteBlockA());
            node.ExecutedFunc = context => { context.Subject.TestValueString = "Completed"; return(Task.FromResult(NodeResultStatus.Succeeded)); };

            var        testObject = new TestObjectA();
            NodeResult result     = await node.ExecuteAsync(testObject);

            node.Status.Should().Be(NodeRunStatus.Completed);
            result.Status.Should().Be(NodeResultStatus.Succeeded);
            result.GetSubjectAs <TestObjectA>().TestValueString.Should().Be("Completed");
        }
Exemplo n.º 12
0
        public async void Subject_Of_Inherited_Type_Works_With_Func_Node()
        {
            var node = new FuncNode <TestObjectA>();

            node.ShouldExecuteFunc = context => Task.FromResult(((TestObjectA)context.Subject).TestValueInt == 0);
            node.ExecutedFunc      = context => { context.Subject.TestValueString = "Completed"; return(Task.FromResult(NodeResultStatus.Succeeded)); };

            var        testObject = new TestObjectASub();
            NodeResult result     = await node.ExecuteAsync(testObject);

            node.Status.ShouldEqual(NodeRunStatus.Completed);
            result.Status.ShouldEqual(NodeResultStatus.Succeeded);
            result.GetSubjectAs <TestObjectA>().TestValueString.ShouldEqual("Completed");
        }
Exemplo n.º 13
0
        public async void Successful_FuncNode_Values_Match_Expected()
        {
            var node = new FuncNode <TestObjectA>();

            node.AddShouldExecute(context => Task.FromResult(context.Subject.TestValueInt == 0));
            node.ExecutedFunc = context => { context.Subject.TestValueString = "Completed"; return(Task.FromResult(NodeResultStatus.Succeeded)); };

            var        testObject = new TestObjectA();
            NodeResult result     = await node.ExecuteAsync(testObject);

            node.Status.ShouldEqual(NodeRunStatus.Completed);
            result.Status.ShouldEqual(NodeResultStatus.Succeeded);
            result.GetSubjectAs <TestObjectA>().TestValueString.ShouldEqual("Completed");
        }
Exemplo n.º 14
0
        public async void FuncNode_With_ShouldExecute_False_Shouldnt_Run()
        {
            var node = new FuncNode <TestObjectA>();

            node.AddShouldExecute(context => Task.FromResult(context.Subject.TestValueInt == 5));
            node.ExecutedFunc = context => { context.Subject.TestValueString = "Completed"; return(Task.FromResult(NodeResultStatus.Succeeded)); };

            var        testObject = new TestObjectA();
            NodeResult result     = await node.ExecuteAsync(testObject);

            node.Status.ShouldEqual(NodeRunStatus.NotRun);
            result.Status.ShouldEqual(NodeResultStatus.NotRun);
            result.GetSubjectAs <TestObjectA>().TestValueString.ShouldBeNull();
        }
Exemplo n.º 15
0
        private void DumpFunction(FuncNode curFunc)
        {
            dumper.Dump(curFunc.Function.Header.Name);
            dumper.Dump(curFunc.Function.Header.LineDefined);
            dumper.Dump(curFunc.Function.Header.LastLineDefined);
            dumper.Dump(curFunc.Function.Header.Nups);
            dumper.Dump(curFunc.Function.Header.NumOfArgs);
            dumper.Dump(curFunc.Function.Header.IsVarArg);
            dumper.Dump(curFunc.Function.Header.MaxStackSize);

            DumpCode(curFunc.Function.Code);
            DumpConstants(curFunc);
            DumpDebug(curFunc.Function.Debug);
        }
Exemplo n.º 16
0
 /// <summary>
 /// This method prints the funcNode and make an indentation
 /// It accepts the statements, the name of the function and the parameters
 /// </summary>
 /// <param name="funcNode">The node to print.</param>
 /// <returns>Returns null</returns>
 public override object Visit(FuncNode funcNode)
 {
     Print("FuncNode");
     Indent++;
     //funcNode.Accept(this);
     if (funcNode.Statements.Any())
     {
         funcNode.Statements.ForEach(node => node.Accept(this));
     }
     funcNode.Name.Accept(this);
     funcNode.FunctionParameters.ForEach(node => node.Accept(this));
     Indent--;
     return(null);
 }
Exemplo n.º 17
0
        /// <summary>
        /// This method visits a function node
        /// The switch case checks for the function type
        /// Then the input parameters are accepted
        /// Then the function is assigned to a new scope and the statements are accepted
        /// </summary>
        /// <param name="funcNode">The name of the node</param>
        /// <returns>Returns a function</returns>
        public override object Visit(FuncNode funcNode)
        {
            string func = "";

            switch ((funcNode.SymbolType?.Type.ToString() ?? "void"))
            {
            case "void":
                func += "void ";
                break;

            case "NUMERIC":
                if (funcNode.SymbolType.IsFloat)
                {
                    func += "float ";
                }
                else
                {
                    func += "int ";
                }
                break;

            case "BOOL":
                func += "bool ";
                break;

            case "STRING":
                func += "string ";
                break;

            default:
                new InvalidCodeException($"Invalid return type in function {funcNode.Name.Id} at {funcNode.Line}:{funcNode.Offset}");
                break;
            }

            func += funcNode.Name.Id + "(";

            funcNode.FunctionParameters.ForEach(node => func += findFuncInputparam(node, funcNode) + node.Accept(this) + (funcNode.FunctionParameters.IndexOf(node) < funcNode.FunctionParameters.Count - 1 ? ", " : " "));

            func   += ")";
            Global += func + ";";
            Global += "";
            func   += "{";
            if (funcNode.Statements.Any())
            {
                funcNode.Statements.ForEach(node => func += node.Accept(this));
            }
            func += "}";
            return(func);
        }
Exemplo n.º 18
0
    public int AddFunc(string name, int entryPoint)
    {
        if (GetFuncByName(name) != null)
        {
            return(ERROR_IDX);
        }

        var newFunc = new FuncNode {
            name = name, entryPoint = entryPoint, index = table.Length
        };

        table.Push(newFunc);

        return(newFunc.index);
    }
Exemplo n.º 19
0
        protected void CompileFuncNode(FuncNode node)
        {
            string className   = HoistNamespace(node.className);
            string methodName  = node.methodName;
            string returnValue = "";

            // Declare outputs / get inputs
            List <string> args = new List <string>();

            for (int i = 0; i < node.ports.Count; i++)
            {
                Port   port         = node.ports[i];
                string variableName = PortToVariableName(port);

                // Handle return value separately, since it's not an argument
                if (node.hasReturnValue && i == node.ports.Count - 1)
                {
                    returnValue = $"{HoistNamespace(port.type)} {variableName} = ";
                    continue;
                }

                // Declare out variables
                if (!port.isInput)
                {
                    AppendLine($"{HoistNamespace(port.type)} {variableName};");
                    args.Add($"out {variableName}");
                }
                else
                {
                    if (port.IsConnected)
                    {
                        Port outputPort = port.ConnectedPorts[0];
                        CompileInputs(outputPort);
                        args.Add(PortToVariableName(outputPort));
                    }
                    else
                    {
                        // Constant default (actual inline editables / non default() not yet supported)
                        args.Add(DefaultValue(port.type).ToString());
                    }
                }
            }


            // Execute the underlying function
            AppendLine($"{returnValue}{className}.{methodName}({string.Join(", ", args)});");
        }
Exemplo n.º 20
0
        static void Main(string[] args)
        {
            var functions = new ImageProcessingFunctions();

            // Keep the start node separately to provide an input
            var startNode = new FuncNode <Bitmap, BitmapRegion>(functions.DivideIn4Regions);

            var pipeline = startNode
                           .ForEachOutput(x => new[] { functions.ExtractToNewBitmap(x) })
                           .ForEachOutput(x => functions.DivideIn4Regions(x))
                           .ForEachOutput(x => new[] { functions.ExtractToNewBitmap(x) })
                           .ForEachOutput(x => functions.DivideIn4Regions(x))
                           .ForEachOutput(x => new[] { functions.ExtractToNewBitmap(x) })
                           .CollectAllOutputsToOneArray()
                           .ForArray(x => new[] { functions.MergeRegions(x) })
                           .ForEachOutput(x =>
            {
                var fi = new FileInfo(@"..\..\..\output.png");
                x.Save(fi.FullName, ImageFormat.Png);
                return(new[] { fi });
            });

            var filePath = "..\\..\\..\\..\\images\\image1.jpg";

            using (var bitmap = new Bitmap(filePath))
            {
                startNode.SetInput(bitmap);

                pipeline
                .Process()
                .Output[0]
                .ShowFile();
            }

            Console.ReadLine();

            filePath = "..\\..\\..\\..\\images\\image2.jpg";
            using (var bitmap = new Bitmap(filePath))
            {
                startNode.SetInput(bitmap);

                pipeline
                .Process()
                .Output[0]
                .ShowFile();
            }
        }
Exemplo n.º 21
0
        public override string ToString(FuncNode parent)
        {
            if (Value.Denominator == 1 || !parent.IsKnown)
            {
                return(Name);
            }

            if (parent.FunctionType == KnownFuncType.Mult || parent.FunctionType == KnownFuncType.Div ||
                parent.FunctionType == KnownFuncType.Pow || parent.FunctionType == KnownFuncType.Neg)
            {
                return('(' + Name + ')');
            }
            else
            {
                return(Name);
            }
        }
Exemplo n.º 22
0
        public override string Visit(FuncNode node)
        {
            var parameters = string.Join(", ", node.Parameters.Select(param => param.Id));

            Scope = Scope.CreateChildScope(node);
            foreach (var param in node.Parameters)
            {
                Scope.AddVariable(param.Id, param);
            }

            var body = Visit(node.Body);

            var result = $"function ({parameters}) {{\nreturn {body};\n}}";

            Scope = Scope.Parent;
            return(result);
        }
Exemplo n.º 23
0
 /// <summary>
 /// This method type checks the CallNode node in the AST.
 /// </summary>
 /// <param name="callNode">The node to check.</param>
 /// <returns>Type context of the function called</returns>
 public override object Visit(CallNode callNode)
 {
     try
     {
         if (SymbolTableObject.FunctionDefinitions.Any(func => func.Name.Id == callNode.Id.Id && func.FunctionParameters.Count == callNode.Parameters.Count))
         {
             FuncNode    n = SymbolTableObject.FunctionDefinitions.First(node => node.Name.Id == callNode.Id.Id && node.FunctionParameters.Count == callNode.Parameters.Count);
             TypeContext ctx;
             if (n.Statements.Any())
             {
                 if (n.Statements.Last().IsType(typeof(ReturnNode)))
                 {
                     _temp        = CurrentScope;
                     CurrentScope = GlobalScope.FindChild($"func_{n.Name.Id}_{n.Line}");
                     ctx          = (TypeContext)n.Statements.Last().Accept(this);
                     CurrentScope = _temp;
                 }
                 else
                 {
                     ctx = new TypeContext(TokenType.FUNC);
                 }
             }
             else
             {
                 ctx = new TypeContext(TokenType.FUNC);
             }
             return(ctx);
         }
         else if (SymbolTableObject.PredefinedFunctions.Any(func => func.Name.Id == callNode.Id.Id && func.FunctionParameters.Count == callNode.Parameters.Count))
         {
             TypeContext ctx = SymbolTableObject.PredefinedFunctions.First(node => node.Name.Id == callNode.Id.Id && node.FunctionParameters.Count == callNode.Parameters.Count).SymbolType;
             return(ctx);
         }
         else
         {
             new NotDefinedException($"A function '{callNode.Id.Id}' with {callNode.Parameters.Count} parameters has not been defined. Error at {callNode.Line}:{callNode.Offset} ");
             return(null);
         }
     }
     catch
     {
         new NotDefinedException($"Undefined function call at {callNode.Line}:{callNode.Offset}");
         return(null);
     }
 }
Exemplo n.º 24
0
        static void Main(string[] args)
        {
            var startNode = new FuncNode <int, int>(x =>
            {
                Console.WriteLine("Pow 2 and double");
                return(new[] { x *x, x *x });
            });

            var pipeline = startNode
                           .ForEachOutput(x =>
            {
                Console.WriteLine("Make an array of two elements and add 1 and 2");
                return(new[] { x + 1, x + 2 });
            })
                           .ForEachOutput(new SumNode())
                           //.ForEachOutput(x => new[] { x + 3, x + 4 })
                           //.ForEachOutput(x => new[] {x + 5, x + 6})*
                           //.ForEachOutput(x => new[] {x + 1})
                           //.ForEachOutput(x => new[] {x + 4})
                           .CollectAllOutputsToOneArray()
                           .ForArray(x =>
            {
                Console.WriteLine("Gather to one string");
                var sb = new StringBuilder();
                for (var i = 0; i < x.Length; i++)
                {
                    sb.AppendFormat("{0} HQ ", x[i]);
                }
                return(new[] { sb.ToString() });
            });


            startNode.SetInput(5);
            var result1 = pipeline.Process()
                          .Output[0];

            Console.WriteLine(result1);

            startNode.SetInput(10);
            pipeline.Process();
            var result2 = pipeline.Process()
                          .Output[0];

            Console.WriteLine(result2);
        }
Exemplo n.º 25
0
        void LoadFunction(ref FuncNode upperNode)
        {
            FuncNode curNode = new FuncNode();

            curNode.Function.Header.Name            = undumper.LoadString();
            curNode.Function.Header.LineDefined     = undumper.LoadInt();
            curNode.Function.Header.LastLineDefined = undumper.LoadInt();
            curNode.Function.Header.Nups            = undumper.LoadByte();
            curNode.Function.Header.NumOfArgs       = undumper.LoadByte();
            curNode.Function.Header.IsVarArg        = undumper.LoadByte();
            curNode.Function.Header.MaxStackSize    = undumper.LoadByte();

            curNode.Function.Code      = LoadCode();
            curNode.Function.Constants = LoadConstants(ref curNode);
            curNode.Function.Debug     = LoadDebug();

            upperNode.Children.Add(curNode);
        }
Exemplo n.º 26
0
        public async Task Can_Add_Inherited_Func_Node_To_Pipleline()
        {
            var testNode = new FuncNode <TestObjectA>();

            testNode.AddShouldExecute(context => Task.FromResult(context.Subject.TestValueInt == 0));
            testNode.ExecutedFunc = context => { context.Subject.TestValueString = "Completed"; return(Task.FromResult(NodeResultStatus.Succeeded)); };

            var testObject = new TestObjectASub();

            var pipeline = new PipelineNode <TestObjectASub>();

            pipeline.AddChild(testNode);

            var result = await pipeline.ExecuteAsync(testObject);

            testNode.Status.Should().Be(NodeRunStatus.Completed);
            result.Status.Should().Be(NodeResultStatus.Succeeded);
        }
Exemplo n.º 27
0
        public int AddFunc(string Name, int EntryPoint)
        {
            if (GetFuncByName(Name) != null)
            {
                return(-1);
            }

            var Func = new FuncNode();

            Func.Name       = Name;
            Func.EntryPoint = EntryPoint;
            FuncTable_.Add(Func);
            var Index = FuncTable_.Count - 1;

            Func.Index = Index;

            return(Index);
        }
Exemplo n.º 28
0
        private void DumpConstants(FuncNode curFunc)
        {
            dumper.Dump(curFunc.Function.Constants.Count);

            foreach (var cur in curFunc.Function.Constants)
            {
                dumper.Dump((byte)cur.Type);

                switch (cur.Type)
                {
                case ConstantType.LUA_TNIL:

                    break;

                case ConstantType.LUA_TBOOLEAN:
                    dumper.Dump((cur as LuaBoolean).Value);
                    break;

                case ConstantType.LUA_TNUMBER:
                    dumper.Dump((cur as LuaNumber).Value);
                    break;

                case ConstantType.LUA_TSTRING:
                    dumper.Dump((cur as LuaString).Value);
                    break;

                default:
                    break;
                }
            }

            dumper.Dump(curFunc.Children.Count);
            foreach (var cur in curFunc.Children)
            {
                DumpFunction(cur);
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// This method type checks the ProgramNode node in the AST.
        /// This is the entry point for the type checker
        /// </summary>
        /// <param name="programNode">The node to check.</param>
        /// <returns>Returns null</returns>
        public override object Visit(ProgramNode programNode)
        {
            programNode.Statements.ForEach(stmnt => stmnt.Accept(this));
            programNode.FunctionDefinitons.ForEach(func =>
            {
                if (!(SymbolTableObject.FunctionDefinitions.Where(fn => fn.Name.Id == func.Name.Id && func.FunctionParameters.Count == fn.FunctionParameters.Count).Count() > 1))
                {
                    if (SymbolTableObject.FunctionCalls.Any(cn => cn.Id.Id == func.Name.Id && cn.Parameters.Count == func.FunctionParameters.Count))
                    {
                        CallNode cn             = SymbolTableObject.FunctionCalls.First(cn => cn.Id.Id == func.Name.Id && cn.Parameters.Count == func.FunctionParameters.Count);
                        FuncNode declaredFunc   = SymbolTableObject.FunctionDefinitions.First(fn => fn.Name.Id == func.Name.Id);
                        SymbolTableObject scope = GlobalScope.FindChild($"func_{declaredFunc.Name.Id}_{declaredFunc.Line}");
                        for (int i = 0; i < cn.Parameters.Count; i++)
                        {
                            if (cn.Parameters[i].SymbolType.Type == VAR)
                            {
                                continue;
                            }
                            scope.UpdateTypedef(declaredFunc.FunctionParameters[i], cn.Parameters[i].SymbolType, scope.Name, true);
                        }
                    }
                    func.Accept(this);
                }
                else
                {
                    new MultipleDefinedException($"A function '{func.Name.Id}' with {func.FunctionParameters.Count} parameters has already been defined. Error at {func.Line}:{func.Offset}");
                }
            });

            if (programNode.LoopFunction == null)
            {
                new NotDefinedException("Loop function was not defined.");
                return(null);
            }
            programNode.LoopFunction.Accept(this);
            return(null);
        }
Exemplo n.º 30
0
 public void Accept(FuncNode node)
 {
     var temp = method;
     compileFunc(node);
     if (!module.ObjectPool.ContainsKey(method.GetHashCode()))
         module.ObjectPool.Add(method.GetHashCode(), method);
     if (!table.ContainsSymbol(method.Name))
         table.AddSymbol(method.Name);
     temp.Emit(node.SourceLocation, InstructionType.PushObject, method.GetHashCode());
     temp.Emit(node.SourceLocation, InstructionType.StoreLocal, table.GetSymbol(method.Name));
     method = temp;
 }
Exemplo n.º 31
0
    private void FirstParse()
    {
        Token token = null;

        do
        {
            token = lexer.NextToken();

//			Console.WriteLine ( token );

            switch (token.type)
            {
            case TokenType.SET_STACK_SIZE:

                // set_stack_size 只能出现在全局范围内
                if (isFuncActive)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_LOCAL_SETSTACKSIZE, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                break;

            case TokenType.FUNC:

                var funcNameToken = lexer.NextToken();

                if (funcNameToken.type != TokenType.IDENT)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_FUNC_NAME_ERROR, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                isFuncActive = true;
                var funcIdx = script.funcTable.AddFunc(funcNameToken.value, instrStreamSize);

                if (funcIdx == FuncTable.ERROR_IDX)
                {
                    throw new SyntaxError(
                              string.Format(Messages.ERROR_MSG_FUNC_DUPLICATE_DEFINITION,
                                            funcNameToken.value), token.span.Start.Line, token.span.Start.Column);
                }

                currentFunc = script.funcTable.GetFuncByName(funcNameToken.value);

                // 跳过函数名单词后面的可选换行符
                var funcNameNextToken = lexer.NextToken();
                while (funcNameNextToken.type == TokenType.NEWLINE)
                {
                    funcNameNextToken = lexer.NextToken();
                }

                if (funcNameNextToken.type != TokenType.OPEN_BRACE)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_FUNC_START_MISMATCH, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                // 入口函数检查
                if (funcNameToken.value == XASMLexer.Keyworkd_Main)
                {
                    script.isMainFuncPresent = true;
                    script.mainFuncIndex     = currentFunc.index;
                }

//					lexer.RollingBackToTheTokenStart ( funcNameNextToken );

                instrStreamSize++;
                break;

            case TokenType.CLOSE_BRACE:

                // 只能出现在函数体结尾
                if (!isFuncActive)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_FUNC_END_MISMATCH, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                script.funcTable.SetFuncInfo(currentFunc.name, currentFunc.paramCount, currentFunc.localDataSize);

                isFuncActive = false;
                break;

            /*
             * var (VarName)([ArraySize])
             */
            case TokenType.VAR:

                var varNameToken = lexer.NextToken();

                if (varNameToken.type != TokenType.IDENT)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_VAR_NAME_ERROR, token.span.Start.Line,
                                          token.span.Start.Column);
                }

//					Console.WriteLine ( varNameToken );

                int  arraySize   = 1;
                char varNextChar = lexer.PeekChar(1);

                if (varNextChar == XASMLexer.Open_Bracket)
                {
                    if (lexer.NextToken().type != TokenType.OPEN_BRACKET)
                    {
                        throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_START_ERROR, token.span.Start.Line,
                                              token.span.Start.Column);
                    }

                    var varArraySizeToken = lexer.NextToken();
                    if (varArraySizeToken.type != TokenType.INT)
                    {
                        throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_SIZE_FORMAT_ERROR, token.span.Start.Line,
                                              token.span.Start.Column);
                    }
                    if (!int.TryParse(varArraySizeToken.value, out arraySize))
                    {
                        throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_SIZE_FORMAT_ERROR, token.span.Start.Line,
                                              token.span.Start.Column);
                    }

                    if (lexer.NextToken().type != TokenType.CLOSE_BRACKET)
                    {
                        throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_END_ERROR, token.span.Start.Line,
                                              token.span.Start.Column);
                    }
                }

                int stackIndex;
                if (isFuncActive)
                {
                    stackIndex = -(2 + currentFunc.localDataSize);

                    if (script.symbolTable.AddSymbol(varNameToken.value, arraySize, stackIndex, currentFunc.index) == -1)
                    {
                        throw new SyntaxError(
                                  string.Format(Messages.ERROR_MSG_FUNC_VAR_DUPLICATE_DEFINITION,
                                                varNameToken.value), token.span.Start.Line, token.span.Start.Column);
                    }

                    currentFunc.localDataSize += arraySize;
                }
                else
                {
                    stackIndex = script.globalDataSize;
                    if (script.symbolTable.AddSymbol(varNameToken.value, arraySize, stackIndex, -1) == -1)
                    {
                        throw new SyntaxError(
                                  string.Format(Messages.ERROR_MSG_GLOBAL_VAR_DUPLICATE_DEFINITION,
                                                varNameToken.value), token.span.Start.Line, token.span.Start.Column);
                    }
                    script.globalDataSize += arraySize;
                }

                break;

            /*
             * Param (ParameterName)
             */
            case TokenType.PARAM:

                // 只能出现在函数体中
                if (!isFuncActive)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_FUNC_PARAM_WRONG_LOCATION, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                var paramNameToken = lexer.NextToken();

                if (paramNameToken.type != TokenType.IDENT)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_FUNC_PARAM_WRONG_FORMAT, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                currentFunc.paramCount++;
                break;

            /*
             * (IdentifierName):
             */
            case TokenType.IDENT:

                // 跳转只能出现在函数体中
                if (!isFuncActive)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_LABEL_WRONG_LOCATION, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                var labelToken         = token;
                var labelNameNextToken = lexer.NextToken();

                if (labelNameNextToken.type != TokenType.COLON)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_LABEL_WRONG_FORMAT, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                int targetIndex = instrStreamSize - 1;

                var labelIdx = script.labelTable.AddLabel(labelToken.value, targetIndex, currentFunc.index);

                if (labelIdx == FuncTable.ERROR_IDX)
                {
                    throw new SyntaxError(
                              string.Format(Messages.ERROR_MSG_LABEL_DUPLICATE_DEFINITION,
                                            labelToken.value), token.span.Start.Line, token.span.Start.Column);
                }
                break;

            /*
             * 指令定义
             */
            case TokenType.INSTR:

                // 指令只能出现在函数体中
                if (!isFuncActive)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_INSTR_WRONG_LOCATION, token.span.Start.Line,
                                          token.span.Start.Column);
                }

                instrStreamSize++;

                Token instrEndToken = null;
                do
                {
                    instrEndToken = lexer.NextToken();
                }while (instrEndToken.type != TokenType.NEWLINE || instrEndToken.type == TokenType.EOF);
                break;

            case TokenType.EOF:
                break;

            default:

                if (token.type != TokenType.NEWLINE)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_INVALID_TOKEN + $" {token}", token.span.Start.Line,
                                          token.span.Start.Column);
                }

                break;
            }
        } while (token.type != TokenType.EOF);

        if (isFuncActive)
        {
            throw new SyntaxError(Messages.ERROR_MSG_FUNC_END_NOT_FOUND, token.span.Start.Line,
                                  token.span.Start.Column);
        }

//		Console.WriteLine ( $"指令流Size: {instrStreamSize}" );
    }
Exemplo n.º 32
0
        private HassiumMethod compileFunc(FuncNode node)
        {
            if (!module.ConstantPool.ContainsKey(node.Name.GetHashCode()))
                module.ConstantPool.Add(node.Name.GetHashCode(), node.Name);

            method = new HassiumMethod();
            method.Parent = new HassiumClass();
            method.IsPrivate = node.IsPrivate;
            method.Name = node.Name;
            method.ReturnType = node.ReturnType;
            method.SourceRepresentation = node.GetSourceRepresentation();

            table.PushScope();

            foreach (var param in node.Parameters)
                method.Parameters.Add(param, table.AddSymbol(param.Name));
            if (node.Children[0] is CodeBlockNode)
                node.Children[0].VisitChildren(this);
            else
                node.Children[0].Visit(this);
            table.PopScope();
            return method;
        }
Exemplo n.º 33
0
 public MethodBuilder(string name, List<FuncParameter> parameters, string returnType = "")
 {
     FunctionBody = new CodeBlockNode();
     Function = new FuncNode(ModuleBuilder.SourceLocation, name, parameters, FunctionBody, returnType);
 }
Exemplo n.º 34
0
 public void Accept(FuncNode node)
 {
     node.VisitChildren(this);
 }