public void Visit(ASTWhile whileStatement, Function function) { // do condition int condition = function.Code.Count; whileStatement.Condition.Accept(this, function); // branch out if condition evaluates to false function.Code.Write(OpCodeFactory.BranchIfFalse(0)); int conditionBranch = function.Code.Count - 1; // compile body whileStatement.Body.Accept(this, function); // branch back to the condition function.Code.Write(OpCodeFactory.Branch((uint)condition)); int end = function.Code.Count; // set the conditional branch offset function.Code[conditionBranch].As <BranchIfFalse>().Argument = (uint)end; // fill breaks/continues for (int i = condition; i < end; i++) { var instruction = function.Code[i]; if (instruction is Branch breakBranch && breakBranch.Argument == Break) // break, jump to end { breakBranch.Argument = (uint)end; }
public void Visit(ASTMemberFunction functionDeclaration) { var _class = _environment.FindClass(functionDeclaration.BaseClass); if (_class == null) { throw new CompilerException($"Class '{functionDeclaration.BaseClass}' does not exist."); } var function = _class.FindFunction(functionDeclaration.Name); if (function == null) { throw new CompilerException($"Class '{functionDeclaration.BaseClass}' does not define function '{functionDeclaration.Name}'."); } for (int i = functionDeclaration.Arguments.Count - 1; i >= 0; i--) { function.Code.Write(OpCodeFactory.Set(ObjectFactory.String(functionDeclaration.Arguments[i]))); function.Code.Write(OpCodeFactory.Pop); } if (functionDeclaration.Body != null) { functionDeclaration.Body.Accept(this, function); // We add this in case the user explicitly doesn't return anything in which case the function is void. function.Code.Write(OpCodeFactory.Push(ObjectFactory.Null)); function.Code.Write(OpCodeFactory.Return); } }
public void Visit(ASTFunctionDefinition functionDefinition, Class _class) { var func = ObjectFactory.Function(functionDefinition.Name, functionDefinition.Arguments); if (functionDefinition.Body != null) { functionDefinition.Body.Accept(this, func); // return null if script doesn't explicitly return something func.Code.Write(OpCodeFactory.Push(ObjectFactory.Null)); func.Code.Write(OpCodeFactory.Return); } _class.AddFunction(func); }
public void Visit(ASTIf astIf, Function function) { // Compile condition astIf.Condition.Accept(this, function); // If condition evaluates to false, branch past the if part function.Code.Write(OpCodeFactory.BranchIfFalse(0)); var index = function.Code.Count - 1; // Compile if-part astIf.IfPart.Accept(this, function); // Set the offset after compiling the if-part function.Code[index].As <BranchIfFalse>().Argument = (uint)function.Code.Count; if (astIf.ElsePart != null) { astIf.ElsePart.Accept(this, function); } }
private void CreateGeneralClasses() { // TODO: work on class implementation var table = new Class("table"); var func = new Function("count", new List <string> { "tname" }); func.Code.Write(OpCodeFactory.Set(ObjectFactory.String("tname"))); func.Code.Write(OpCodeFactory.Pop); func.Code.Write(OpCodeFactory.Reference(ObjectFactory.String("tname"))); func.Code.Write(OpCodeFactory.Return); table.AddFunction(func); var constructor = new Function("table", new List <string>()); constructor.Code.Write(OpCodeFactory.Push(ObjectFactory.Null)); constructor.Code.Write(OpCodeFactory.Return); table.AddFunction(constructor); _classes.Add(table); }
public void Visit(ASTGlobalFunction functionDeclaration) { var newFunction = ObjectFactory.Function(functionDeclaration.Name, functionDeclaration.Arguments); _environment.AddFunction(newFunction); for (int i = functionDeclaration.Arguments.Count - 1; i >= 0; i--) { newFunction.Code.Write(OpCodeFactory.Set(ObjectFactory.String(functionDeclaration.Arguments[i]))); newFunction.Code.Write(OpCodeFactory.Pop); } if (functionDeclaration.Body != null) { functionDeclaration.Body.Accept(this, newFunction); // We add this in case the user explicitly doesn't return anything in which case the function is void. newFunction.Code.Write(OpCodeFactory.Push(ObjectFactory.Null)); newFunction.Code.Write(OpCodeFactory.Return); } }
public static SVRule Build(SVRuleGene gene) { var OpCodes = gene.OpCodes.Select(t => OpCodeFactory.Build(t)).ToList(); return(new SVRule(OpCodes)); }