/// <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(""); } }
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); }
/// <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); }
void LoadFunctions() { FunctionTree = new FuncNode(); LoadFunction(ref FunctionTree); FunctionTree = FunctionTree.Children[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"); }
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(); }
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); }
/// <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); }
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); }
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"); }
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"); }
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"); }
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(); }
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); }
/// <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); }
/// <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); }
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); }
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)});"); }
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(); } }
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); } }
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); }
/// <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); } }
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); }
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); }
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); }
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); }
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); } }
/// <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); }
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; }
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}" ); }
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; }
public MethodBuilder(string name, List<FuncParameter> parameters, string returnType = "") { FunctionBody = new CodeBlockNode(); Function = new FuncNode(ModuleBuilder.SourceLocation, name, parameters, FunctionBody, returnType); }
public void Accept(FuncNode node) { node.VisitChildren(this); }