public static CompilationBundle Compile(BuildContext buildContext) { using (new PerformanceSection("CompilationBundle.Compile")) { Parser parser = new Parser(buildContext, null); Crayon.ParseTree.Executable[] resolvedParseTree = parser.ParseAllTheThings(); ByteCodeCompiler bcc = new ByteCodeCompiler(); ByteBuffer buffer = bcc.GenerateByteCode(parser, resolvedParseTree); string jsFilePrefix = buildContext.JsFilePrefix == null ? "" : ("/" + buildContext.JsFilePrefix.Trim('/') + "/"); return(new CompilationBundle() { ByteCode = buffer, LibrariesUsed = parser.LibraryManager.LibrariesUsed, ProjectID = buildContext.ProjectID, Version = buildContext.Version, Description = buildContext.Description, GuidSeed = buildContext.GuidSeed, DefaultTitle = buildContext.DefaultTitle, JsFilePrefix = jsFilePrefix, IosBundlePrefix = buildContext.IosBundlePrefix, IconPath = buildContext.IconFilePath, WindowWidth = buildContext.WindowWidth, WindowHeight = buildContext.WindowHeight, }); } }
public static void Compile(ParserContext parser, ByteBuffer buffer, FunctionReference funcRef, bool outputUsed) { ByteCodeCompiler.EnsureUsed(funcRef, outputUsed); FunctionDefinition funcDef = funcRef.FunctionDefinition; int classIdStaticCheck = 0; int type = 0; if (funcDef.Owner is ClassDefinition) { if (funcDef.Modifiers.HasStatic) { classIdStaticCheck = ((ClassDefinition)funcDef.Owner).ClassID; type = 2; } else { type = 1; } } buffer.Add(funcRef.FirstToken, OpCode.PUSH_FUNC_REF, funcDef.FunctionID, type, classIdStaticCheck); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, ForEachLoop forEachLoop) { bcc.CompileExpression(parser, buffer, forEachLoop.IterationExpression, true); buffer.Add( forEachLoop.IterationExpression.FirstToken, OpCode.VERIFY_TYPE_IS_ITERABLE, forEachLoop.ListLocalId.ID, forEachLoop.IndexLocalId.ID); ByteBuffer body = new ByteBuffer(); ByteBuffer body2 = new ByteBuffer(); bcc.Compile(parser, body2, forEachLoop.Code); body.Add( forEachLoop.FirstToken, OpCode.ITERATION_STEP, body2.Size + 1, forEachLoop.IterationVariableId.ID, forEachLoop.IndexLocalId.ID, forEachLoop.ListLocalId.ID); body2.Add(null, OpCode.JUMP, -body2.Size - 2); body.Concat(body2); body.ResolveBreaks(); body.ResolveContinues(); buffer.Concat(body); }
public async void Execute(string program, Dictionary <string, object> variablesIn) { CodeObject compiledProgram = null; try { compiledProgram = ByteCodeCompiler.Compile(program, variablesIn); } catch (Exception ex) { WriteStdout(ex.Message); return; } var receipt = _scheduler.Schedule(compiledProgram); foreach (var variableName in variablesIn.Keys) { receipt.Frame.SetVariable(variableName, variablesIn[variableName]); } while (!_scheduler.Done) { await _scheduler.Tick(); } if (receipt.Completed) { if (receipt.EscapedExceptionInfo != null) { WriteStdout($"{receipt.EscapedExceptionInfo.SourceException}"); } WriteStdout("Done."); } }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, IfStatement ifStatement) { bcc.CompileExpression(parser, buffer, ifStatement.Condition, true); ByteBuffer trueCode = new ByteBuffer(); bcc.Compile(parser, trueCode, ifStatement.TrueCode); ByteBuffer falseCode = new ByteBuffer(); bcc.Compile(parser, falseCode, ifStatement.FalseCode); if (falseCode.Size == 0) { if (trueCode.Size == 0) { buffer.Add(ifStatement.Condition.FirstToken, OpCode.POP); } else { buffer.Add(ifStatement.Condition.FirstToken, OpCode.JUMP_IF_FALSE, trueCode.Size); buffer.Concat(trueCode); } } else { trueCode.Add(null, OpCode.JUMP, falseCode.Size); buffer.Add(ifStatement.Condition.FirstToken, OpCode.JUMP_IF_FALSE, trueCode.Size); buffer.Concat(trueCode); buffer.Concat(falseCode); } }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, DictionaryDefinition dictDef, bool outputUsed) { if (!outputUsed) { throw new ParserException(dictDef, "Cannot have a dictionary all by itself."); } int itemCount = dictDef.Keys.Length; List <Expression> expressionList = new List <Expression>(); for (int i = 0; i < itemCount; ++i) { expressionList.Add(dictDef.Keys[i]); expressionList.Add(dictDef.Values[i]); } bcc.CompileExpressionList(parser, buffer, expressionList, true); List <int> args = new List <int>(); args.Add(itemCount); args.Add(0); if (dictDef.CompilationScope.IsStaticallyTyped) { CastEncoder.EncodeTypeInfoToIntBuffer(args, dictDef.ResolvedKeyType, false); args[1] = args.Count; CastEncoder.EncodeTypeInfoToIntBuffer(args, dictDef.ResolvedValueType, false); } buffer.Add(dictDef.FirstToken, OpCode.DEF_DICTIONARY, args.ToArray()); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, BooleanCombination boolComb, bool outputUsed) { if (!outputUsed) { throw new ParserException(boolComb, "Cannot have this expression here."); } ByteBuffer rightBuffer = new ByteBuffer(); Expression[] expressions = boolComb.Expressions; bcc.CompileExpression(parser, rightBuffer, expressions[expressions.Length - 1], true); for (int i = expressions.Length - 2; i >= 0; --i) { ByteBuffer leftBuffer = new ByteBuffer(); bcc.CompileExpression(parser, leftBuffer, expressions[i], true); Token op = boolComb.Ops[i]; if (op.Value == "&&") { leftBuffer.Add(op, OpCode.JUMP_IF_FALSE_NO_POP, rightBuffer.Size); } else { leftBuffer.Add(op, OpCode.JUMP_IF_TRUE_NO_POP, rightBuffer.Size); } leftBuffer.Concat(rightBuffer); rightBuffer = leftBuffer; } buffer.Concat(rightBuffer); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, OpChain opChain, bool outputUsed) { if (!outputUsed) { if (opChain.OpToken.Value == "==") { throw new ParserException(opChain.OpToken, "'==' cannot be used like this. Did you mean to use just a single '=' instead?"); } throw new ParserException(opChain, "This expression isn't valid here."); } bcc.CompileExpressionList(parser, buffer, new Expression[] { opChain.Left, opChain.Right }, true); switch (opChain.OpTEMP) { case Ops.EQUALS: case Ops.NOT_EQUALS: buffer.Add(opChain.OpToken, OpCode.EQUALS, opChain.OpTEMP == Ops.EQUALS ? 0 : 1); break; default: buffer.Add(opChain.OpToken, OpCode.BINARY_OP, (int)opChain.OpTEMP); break; } if (!outputUsed) { buffer.Add(null, OpCode.POP); } }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, NegativeSign negativeSign, bool outputUsed) { if (!outputUsed) { throw new ParserException(negativeSign, "This expression does nothing."); } bcc.CompileExpression(parser, buffer, negativeSign.Root, true); buffer.Add(negativeSign.FirstToken, OpCode.NEGATIVE_SIGN); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, BracketIndex bracketIndex, bool outputUsed) { if (!outputUsed) { throw new ParserException(bracketIndex, "This expression does nothing."); } bcc.CompileExpression(parser, buffer, bracketIndex.Root, true); bcc.CompileExpression(parser, buffer, bracketIndex.Index, true); buffer.Add(bracketIndex.BracketToken, OpCode.INDEX); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, BooleanNot boolNot, bool outputUsed) { if (!outputUsed) { throw new ParserException(boolNot, "Cannot have this expression here."); } bcc.CompileExpression(parser, buffer, boolNot.Root, true); buffer.Add(boolNot.FirstToken, OpCode.BOOLEAN_NOT); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, NullCoalescer nullCoalescer, bool outputUsed) { ByteCodeCompiler.EnsureUsed(nullCoalescer, outputUsed); bcc.CompileExpression(parser, buffer, nullCoalescer.PrimaryExpression, true); ByteBuffer secondaryExpression = new ByteBuffer(); bcc.CompileExpression(parser, secondaryExpression, nullCoalescer.SecondaryExpression, true); buffer.Add(nullCoalescer.FirstToken, OpCode.POP_IF_NULL_OR_JUMP, secondaryExpression.Size); buffer.Concat(secondaryExpression); }
public static void Compile(ParserContext parser, ByteBuffer buffer, BaseMethodReference baseMethodReference, bool outputUsed) { ByteCodeCompiler.EnsureUsed(baseMethodReference, outputUsed); int baseClassId = baseMethodReference.ClassToWhichThisMethodRefers.ClassID; buffer.Add( baseMethodReference.DotToken, OpCode.PUSH_FUNC_REF, baseMethodReference.FunctionDefinition.FunctionID, 1, // instance method 0); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Instantiate instantiate, bool outputUsed) { ClassDefinition cd = instantiate.Class; ConstructorDefinition constructor = cd.Constructor; bcc.CompileExpressionList(parser, buffer, instantiate.Args, true); buffer.Add(instantiate.NameToken, OpCode.CALL_FUNCTION, (int)FunctionInvocationType.CONSTRUCTOR, instantiate.Args.Length, constructor.FunctionID, outputUsed ? 1 : 0, cd.ClassID); }
private ByteBuffer GenerateByteCode(BuildContext buildContext, string inputFolder) { Parser userCodeParser = new Parser(null, buildContext, null); ParseTree.Executable[] userCode = userCodeParser.ParseAllTheThings(inputFolder); ByteCodeCompiler bcc = new ByteCodeCompiler(); ByteBuffer buffer = bcc.GenerateByteCode(userCodeParser, userCode); this.LibraryManager = userCodeParser.SystemLibraryManager; this.LibraryBigSwitchStatement = this.LibraryManager.GetLibrarySwitchStatement(this); this.InterpreterCompiler = new InterpreterCompiler(this, userCodeParser.SystemLibraryManager); return(buffer); }
public static void Compile( ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, CoreFunctionInvocation coreFuncInvocation, Expression[] argsOverrideOrNull, Token tokenOverrideOrNull, bool outputUsed) { Token token = tokenOverrideOrNull ?? coreFuncInvocation.FirstToken; Expression[] args = argsOverrideOrNull ?? coreFuncInvocation.Args; if (coreFuncInvocation.FunctionId == (int)CoreFunctionID.TYPE_IS) { ByteCodeCompiler.EnsureUsed(coreFuncInvocation, outputUsed); bcc.CompileExpression(parser, buffer, args[0], true); int typeCount = args.Length - 1; int[] actualArgs = new int[typeCount + 3]; actualArgs[0] = coreFuncInvocation.FunctionId; actualArgs[1] = 1; // output used actualArgs[2] = typeCount; for (int i = typeCount - 1; i >= 0; --i) { IntegerConstant typeArg = args[args.Length - 1 - i] as IntegerConstant; if (typeArg == null) { throw new ParserException(coreFuncInvocation, "typeis requires type enum values."); } actualArgs[3 + i] = typeArg.Value + 1; } buffer.Add(token, OpCode.CORE_FUNCTION, actualArgs); return; } foreach (Expression arg in args) { bcc.CompileExpression(parser, buffer, arg, true); } if (coreFuncInvocation.FunctionId == (int)CoreFunctionID.INT_QUEUE_WRITE_16) { buffer.Add(token, OpCode.CORE_FUNCTION, coreFuncInvocation.FunctionId, outputUsed ? 1 : 0, args.Length - 1); return; } buffer.Add(token, OpCode.CORE_FUNCTION, coreFuncInvocation.FunctionId, outputUsed ? 1 : 0); }
protected void runProgram(string program, Dictionary <string, object> variablesIn, List <ISpecFinder> moduleSpecFinders, int expectedIterations, out FrameContext context) { CodeObject compiledProgram = null; try { compiledProgram = ByteCodeCompiler.Compile(program, variablesIn); } catch (CloacaParseException parseFailed) { Assert.Fail(parseFailed.Message); } Dis.dis(compiledProgram); // TODO: This dependency association is kind of gross. It's almost circular and is broken by assigning // the interpreter reference to the schedular after its initial constructor. var scheduler = new Scheduler(); var interpreter = new Interpreter(scheduler); interpreter.DumpState = true; foreach (var finder in moduleSpecFinders) { interpreter.AddModuleFinder(finder); } scheduler.SetInterpreter(interpreter); var receipt = scheduler.Schedule(compiledProgram); context = receipt.Frame; foreach (string varName in variablesIn.Keys) { context.SetVariable(varName, variablesIn[varName]); } // Waiting on the task makes sure we get punched in the face by any exceptions it throws. // But they'll come rolling in as AggregateExceptions so we'll have to unpack them. var scheduler_task = scheduler.RunUntilDone(); scheduler_task.Wait(); Assert.That(receipt.Completed); if (receipt.EscapedExceptionInfo != null) { receipt.EscapedExceptionInfo.Throw(); } Assert.That(scheduler.TickCount, Is.EqualTo(expectedIterations)); }
private static async Task <InternalCompilationBundle> CompileImpl(CompileRequest compileRequest, Wax.WaxHub waxHub) { ParserContext parserContext = new ParserContext(compileRequest, waxHub); TopLevelEntity[] resolvedParseTree = await parserContext.ParseAllTheThings(); ByteCodeCompiler bcc = new ByteCodeCompiler(); ByteBuffer buffer = bcc.GenerateByteCode(parserContext, resolvedParseTree); return(new InternalCompilationBundle() { ByteCode = ByteCodeEncoder.Encode(buffer), RootScope = parserContext.RootScope, AllScopes = parserContext.ScopeManager.ImportedAssemblyScopes.ToArray(), }); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Ternary ternary, bool outputUsed) { ByteCodeCompiler.EnsureUsed(ternary, outputUsed); bcc.CompileExpression(parser, buffer, ternary.Condition, true); ByteBuffer trueBuffer = new ByteBuffer(); bcc.CompileExpression(parser, trueBuffer, ternary.TrueValue, true); ByteBuffer falseBuffer = new ByteBuffer(); bcc.CompileExpression(parser, falseBuffer, ternary.FalseValue, true); trueBuffer.Add(null, OpCode.JUMP, falseBuffer.Size); buffer.Add(ternary.Condition.FirstToken, OpCode.JUMP_IF_FALSE, trueBuffer.Size); buffer.Concat(trueBuffer); buffer.Concat(falseBuffer); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, DoWhileLoop doWhileLoop) { ByteBuffer loopBody = new ByteBuffer(); bcc.Compile(parser, loopBody, doWhileLoop.Code); loopBody.ResolveContinues(true); // continues should jump to the condition, hence the true. ByteBuffer condition = new ByteBuffer(); bcc.CompileExpression(parser, condition, doWhileLoop.Condition, true); loopBody.Concat(condition); loopBody.Add(doWhileLoop.Condition.FirstToken, OpCode.JUMP_IF_TRUE, -loopBody.Size - 1); loopBody.ResolveBreaks(); buffer.Concat(loopBody); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, ListDefinition listDef, bool outputUsed) { if (!outputUsed) { throw new ParserException(listDef, "List allocation made without storing it. This is likely a mistake."); } foreach (Expression item in listDef.Items) { bcc.CompileExpression(parser, buffer, item, true); } List <int> args = new List <int>() { listDef.Items.Length }; listDef.ResolvedType.ListItemType.BuildEncoding(args); buffer.Add(listDef.FirstToken, OpCode.DEF_LIST, args.ToArray()); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, WhileLoop whileLoop) { ByteBuffer loopBody = new ByteBuffer(); bcc.Compile(parser, loopBody, whileLoop.Code); ByteBuffer condition = new ByteBuffer(); bcc.CompileExpression(parser, condition, whileLoop.Condition, true); condition.Add(whileLoop.Condition.FirstToken, OpCode.JUMP_IF_FALSE, loopBody.Size + 1); condition.Concat(loopBody); condition.Add(null, OpCode.JUMP, -condition.Size - 1); condition.ResolveBreaks(); condition.ResolveContinues(); buffer.Concat(condition); }
public static void Compile( ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, FunctionDefinition funDef, bool isMethod) { ByteBuffer tBuffer = new ByteBuffer(); List <int> offsetsForOptionalArgs = new List <int>(); CompileFunctionArgs(bcc, parser, tBuffer, funDef.ArgNames, funDef.DefaultValues, offsetsForOptionalArgs, funDef.Locals); if (funDef.CompilationScope.IsStaticallyTyped) { EncodeArgTypeCheck(tBuffer, funDef, funDef.ResolvedArgTypes); } bcc.Compile(parser, tBuffer, funDef.Code); List <int> args = new List <int>() { funDef.FunctionID, parser.GetId(funDef.NameToken.Value), // local var to save in GetMinArgCountFromDefaultValuesList(funDef.DefaultValues), funDef.ArgNames.Length, // max number of args supplied isMethod ? (funDef.Modifiers.HasStatic ? 2 : 1) : 0, // type (0 - function, 1 - method, 2 - static method) isMethod ? ((ClassDefinition)funDef.Owner).ClassID : 0, funDef.LocalScopeSize, tBuffer.Size, offsetsForOptionalArgs.Count }; args.AddRange(offsetsForOptionalArgs); buffer.Add( funDef.FirstToken, OpCode.FUNCTION_DEFINITION, funDef.NameToken.Value, args.ToArray()); buffer.Concat(tBuffer); AddDebugSymbolData(buffer, parser, funDef); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Cast castExpression, bool outputUsed) { if (!outputUsed) { throw new ParserException(castExpression, "The output of a cast must be used."); } // This should have been filtered out before now. if (castExpression.Expression.ResolvedType == castExpression.ResolvedType) { throw new Exception(); } bcc.CompileExpression(parser, buffer, castExpression.Expression, true); List <int> args = new List <int>(); EncodeTypeInfoToIntBuffer(args, castExpression.ResolvedType, castExpression.DoIntFloatConversions); buffer.Add(castExpression.FirstToken, OpCode.CAST, args.ToArray()); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, ReturnStatement returnStatement) { if (returnStatement.Owner is ConstructorDefinition) { if (returnStatement.Expression != null) { throw new ParserException(returnStatement, "Cannot return a value from a constructor."); } } if (returnStatement.Expression == null || returnStatement.Expression is NullConstant) { buffer.Add(returnStatement.FirstToken, OpCode.RETURN, 0); } else { bcc.CompileExpression(parser, buffer, returnStatement.Expression, true); buffer.Add(returnStatement.FirstToken, OpCode.RETURN, 1); } }
public static void Compile( ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, CniFunctionInvocation cniFuncInvocation, Expression[] argsOverrideOrNull, Token throwTokenOverrideOrNull, bool outputUsed) { CniFunction cniFunc = cniFuncInvocation.CniFunction; Expression[] args = argsOverrideOrNull ?? cniFuncInvocation.Args; foreach (Expression arg in args) { bcc.CompileExpression(parser, buffer, arg, true); } Token throwToken = throwTokenOverrideOrNull ?? cniFuncInvocation.FirstToken; buffer.Add(throwToken, OpCode.CNI_INVOKE, cniFunc.ID, cniFunc.ArgCount, outputUsed ? 1 : 0); }
public static void Compile(ParserContext parser, ByteBuffer buffer, FieldReference fieldRef, bool outputUsed) { ByteCodeCompiler.EnsureUsed(fieldRef, outputUsed); if (fieldRef.Field.Modifiers.HasStatic) { buffer.Add( fieldRef.FirstToken, OpCode.DEREF_STATIC_FIELD, ((ClassDefinition)fieldRef.Field.Owner).ClassID, fieldRef.Field.StaticMemberID); } else { buffer.Add( fieldRef.FirstToken, OpCode.DEREF_INSTANCE_FIELD, fieldRef.Field.MemberID); } }
private static void CompileImpl(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, Expression root, Token dotToken, Token fieldToken, bool outputUsed) { if (!outputUsed) { throw new ParserException(root.FirstToken, "This expression does nothing."); } bcc.CompileExpression(parser, buffer, root, true); int rawNameId = parser.GetId(fieldToken.Value); int localeId = parser.GetLocaleId(root.Owner.FileScope.CompilationScope.Locale); int localeScopedNameId = rawNameId * parser.GetLocaleCount() + localeId; ClassDefinition cd = root.ClassOwner; int classId = cd == null ? -1 : cd.ClassID; buffer.Add( dotToken, OpCode.DEREF_DOT, rawNameId, localeScopedNameId, classId, root.CompilationScope.ScopeNumId, -1, 0); }
public async Task <object> Load(IInterpreter interpreter, FrameContext context, PyModuleSpec spec) { var foundPath = (string)spec.LoaderState; var inFile = File.ReadAllText(foundPath); var moduleCode = ByteCodeCompiler.Compile(inFile, new Dictionary <string, object>()); await interpreter.CallInto(context, moduleCode, new object[0]); if (context.EscapedDotNetException != null) { throw context.EscapedDotNetException; } var moduleFrame = context.callStack.Pop(); var module = PyModule.Create(spec.Name); for (int local_i = 0; local_i < moduleFrame.LocalNames.Count; ++local_i) { module.__setattr__(moduleFrame.LocalNames[local_i], moduleFrame.Locals[local_i]); } return(module); }
public static void Compile(ByteCodeCompiler bcc, ParserContext parser, ByteBuffer buffer, ForLoop forLoop) { bcc.Compile(parser, buffer, forLoop.Init); ByteBuffer codeBuffer = new ByteBuffer(); bcc.Compile(parser, codeBuffer, forLoop.Code); codeBuffer.ResolveContinues(true); // resolve continues as jump-to-end before you add the step instructions. bcc.Compile(parser, codeBuffer, forLoop.Step); ByteBuffer forBuffer = new ByteBuffer(); bcc.CompileExpression(parser, forBuffer, forLoop.Condition, true); forBuffer.Add(forLoop.Condition.FirstToken, OpCode.JUMP_IF_FALSE, codeBuffer.Size + 1); // +1 to go past the jump I'm about to add. forBuffer.Concat(codeBuffer); forBuffer.Add(null, OpCode.JUMP, -forBuffer.Size - 1); forBuffer.ResolveBreaks(); buffer.Concat(forBuffer); }