public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); if (statement.IsEmptyStatement()) { throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody)); } generator.Resolver.EnterContext(); JumpToken loopToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(loopToken); expression.Prepare(generator, null); // boolean expression.Generate(generator); generator.Resolver.EnterContext(); JumpToken skipToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@continue", loopToken); generator.Resolver.RegisterGoto("@break", skipToken); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.JumpIfFalse(skipToken); statement.Generate(generator, returnType); generator.Assembler.Jump(loopToken); generator.Assembler.SetDestination(skipToken); generator.Resolver.LeaveContext(); generator.Resolver.LeaveContext(); breaks = skipToken.JumpCount > 1; }
public override void Generate(Generator generator) { if (getStatement != null) { generator.Resolver.EnterContext(); generator.Resolver.SetContextParameters(getParameters); generator.Resolver.CurrentFieldName = name.Data + ":get"; generator.AllocateAssembler(); getParameters.Generate(generator); ParameterMetadata thisParam = getParameters.Find("this"); generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference); getStatement.Prepare(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); JumpToken returnToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@return", returnToken); JumpToken recurToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(recurToken); generator.Resolver.RegisterGoto("@recur", recurToken); getStatement.Generate(generator, type); if (!getStatement.Returns()) { throw new CompilerException(getStatement, string.Format(Resource.Culture, Resource.NotAllCodePathsReturnAValue)); } generator.Assembler.SetDestination(returnToken); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "getter:" + ParentDefinition.Name.Data + "." + name.Data); getStatementPointer = generator.Assembler.Region.BaseLocation; generator.Resolver.LeaveContext(); } if (setStatement != null) { generator.Resolver.EnterContext(); generator.Resolver.SetContextParameters(setParameters); generator.Resolver.CurrentFieldName = name.Data + ":set"; generator.AllocateAssembler(); setParameters.Generate(generator); ParameterMetadata thisParam = setParameters.Find("this"); generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference); setStatement.Prepare(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); JumpToken returnToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@return", returnToken); JumpToken recurToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(recurToken); generator.Resolver.RegisterGoto("@recur", recurToken); setStatement.Generate(generator, null); generator.Assembler.SetDestination(returnToken); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "setter:" + ParentDefinition.Name.Data + "." + name.Data); setStatementPointer = generator.Assembler.Region.BaseLocation; generator.Resolver.LeaveContext(); } }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); generator.Resolver.AddVariable(name, type, slot, false); if (assignment != null) { generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); assignment.Generate(generator, returnType); } }
void GenerateLambda(Generator generator) { Assembler oldAssembler = generator.Assembler; offset = oldAssembler.SlotCount(); generator.AllocateAssembler(); Assembler inner = generator.Assembler; generator.Assembler = new LambdaAssembler(this, generator.Assembler); generator.Resolver.EnterContextParentReadOnly(); closureSlot = offset; localSlots.Add(closureSlot, inner.AddParameter()); // closure, or nothing if no fields Parameters p = new Parameters(); for (int i = 0; i < parameters.Count; ++i) { int s = inner.AddParameter(); int ex = offset + localSlots.Count; localSlots.Add(ex, s); generator.Resolver.AddVariable(parameters[i], parameterTypes[i], ex, true); generator.Resolver.AssignSlot(ex); generator.Resolver.RetrieveSlot(this, ex, false); // todo: make warning: treat function arguments as used ParameterMetadata pm = p.AddParameter(parameters[i], parameterTypes[i], parameters[i]); pm.Bind(ex); } generator.Resolver.SetContextParameters(p); statement.Prepare(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); JumpToken returnToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@return", returnToken); JumpToken recurToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(recurToken); generator.Resolver.RegisterGoto("@recur", recurToken); statement.Generate(generator, returnType); generator.Assembler.SetDestination(returnToken); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "lambda:"); functionPointer = generator.Assembler.Region.BaseLocation; generator.Resolver.LeaveContext(); generator.Assembler = oldAssembler; }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); expression.Prepare(generator, null); expression.Generate(generator); generator.Assembler.StoreVariable(slot); generator.Resolver.EnterContext(); generator.Resolver.AddVariable(new Identifier(this, Guid.NewGuid().ToString("B")), expression.TypeReference, slot, true); if (!expression.TypeReference.IsDefinition && !expression.TypeReference.IsStatic) { throw new CompilerException(this, Resource.CanOnlyUseWithOnNotNullClassInstances); } generator.Resolver.SetImplicitFields(slot, expression.TypeReference); statement.Generate(generator, returnType); returns = statement.Returns(); generator.Resolver.LeaveAndMergeContext(); }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); expression.Prepare(generator, null); // boolean expression.Generate(generator); // boolean boolType.GenerateConversion(this, generator, expression.TypeReference); JumpToken elseToken = generator.Assembler.CreateJumpToken(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.JumpIfFalse(elseToken); generator.Resolver.EnterContext(); if (statement.IsEmptyBlock()) { throw new CompilerException(statement, string.Format(Resource.Culture, Resource.IfBranchIsEmpty)); } statement.Generate(generator, returnType); Resolver.Context trueContext = generator.Resolver.LeaveContextAcquire(); if (elseStatement != null) { if (elseStatement.IsEmptyBlock()) { throw new CompilerException(elseStatement, string.Format(Resource.Culture, Resource.IfBranchIsEmpty)); } JumpToken skipElseToken = generator.Assembler.CreateJumpToken(); generator.Assembler.Jump(skipElseToken); generator.Assembler.SetDestination(elseToken); generator.Resolver.EnterContext(); elseStatement.Generate(generator, returnType); returns = statement.Returns() && elseStatement.Returns(); Resolver.Context falseContext = generator.Resolver.LeaveContextAcquire(); generator.Resolver.IntersectContexts(trueContext, falseContext); generator.Resolver.ReleaseContext(falseContext); generator.Assembler.SetDestination(skipElseToken); } else { generator.Assembler.SetDestination(elseToken); } generator.Resolver.ReleaseContext(trueContext); }
public override void Generate(Generator generator) { base.Generate(generator); parent.Generate(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); TypeReference ptr = parent.TypeReference; bool allowNull = ptr.IsNullable && !typeReference.IsNullable; if (!allowNull) { generator.Assembler.CrashIfNull(); } TypeReference str = typeReference; if (str.SupportsImplicit(ptr)) { typeReference.GenerateConversion(this, generator, parent.TypeReference); } else { JumpToken jtNull = null; if (allowNull) { jtNull = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfUnassigned(jtNull); } generator.Assembler.TypeConversionDynamicNotNull(str.Id); JumpToken jtOk = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfAssigned(jtOk); throwCastException.Generate(generator, null); generator.Assembler.SetDestination(jtOk); if (allowNull) { generator.Assembler.SetDestination(jtNull); } } }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); // generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); PlaceholderRef fonCatchJump = null; if (finallyStatement != null) { fonCatchJump = new PlaceholderRef(); generator.Assembler.ExceptionHandlerSetup(fonCatchJump); generator.Resolver.EnterContext(); generator.Resolver.RegisterTryContext(); } PlaceholderRef onCatchJump = null; if (catches.Count > 0) { onCatchJump = new PlaceholderRef(); generator.Assembler.ExceptionHandlerSetup(onCatchJump); } generator.Resolver.EnterContext(); generator.Resolver.RegisterTryContext(); statement.Generate(generator, returnType); returns = statement.Returns(); Resolver.Context statementContext = generator.Resolver.LeaveContextAcquire(); if (catches.Count > 0) { generator.Assembler.ExceptionHandlerRemove(); JumpToken noExceptionJump = generator.Assembler.CreateJumpToken(); generator.Assembler.Jump(noExceptionJump); generator.Assembler.SetDestination(onCatchJump); JumpToken noReturnJump = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfNotMarked(noReturnJump); generator.Assembler.UnmarkType(); ReturnStatement.DoReturn(this, generator); generator.Assembler.SetDestination(noReturnJump); generator.Assembler.StoreVariable(valueSlot); List <JumpToken> escape = new List <JumpToken>(); foreach (Catch c in catches) { generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, c); generator.Assembler.RetrieveVariable(valueSlot); JumpToken noMatch = generator.Assembler.CreateJumpToken(); generator.Assembler.TypeConversionDynamicNotNull(c.type.Id); generator.Assembler.JumpIfUnassigned(noMatch); generator.Assembler.StoreVariable(valueSlot); generator.Resolver.EnterContext(); generator.Resolver.AddVariable(c.identifier, c.type, valueSlot, true); generator.Resolver.AssignSlot(valueSlot); c.statement.Generate(generator, returnType); returns = returns && c.statement.Returns(); generator.Resolver.LeaveContext(); JumpToken jt = generator.Assembler.CreateJumpToken(); escape.Add(jt); generator.Assembler.Jump(jt); generator.Assembler.SetDestination(noMatch); } //unhandled, rethrow generator.Assembler.RetrieveVariable(valueSlot); generator.Assembler.ExceptionHandlerInvoke(); foreach (JumpToken jt in escape) { generator.Assembler.SetDestination(jt); } generator.Assembler.SetDestination(noExceptionJump); } if (finallyStatement != null) { generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, finallyLocation); generator.Resolver.LeaveContext(); generator.Assembler.ExceptionHandlerRemove(); generator.Assembler.Empty(); generator.Assembler.SetDestination(fonCatchJump); JumpToken fnoReturnJump = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfNotMarked(fnoReturnJump); generator.Assembler.UnmarkType(); generator.Assembler.StoreVariable(returnSlot); generator.Assembler.SetDestination(fnoReturnJump); generator.Assembler.StoreVariable(valueSlot); generator.Resolver.EnterContext(); finallyStatement.Generate(generator, returnType); generator.Resolver.LeaveAndMergeContext(); if (catches.Count == 0) // if there are no catches we can be sure the whole try part completed and so we can use the variables initialized by it. { generator.Resolver.MergeContext(statementContext); } generator.Assembler.RetrieveVariable(returnSlot); JumpToken fonExceptionFinallyJump = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfUnassigned(fonExceptionFinallyJump); ReturnStatement.DoReturn(this, generator); generator.Assembler.SetDestination(fonExceptionFinallyJump); generator.Assembler.RetrieveVariable(valueSlot); JumpToken fnoException = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfUnassigned(fnoException); generator.Assembler.ExceptionHandlerInvoke(); generator.Assembler.SetDestination(fnoException); } generator.Resolver.ReleaseContext(statementContext); }
public void GenerateFunction(Generator generator) { Require.False(generated); generated = true; if (redirect != null) { redirect.node.GenerateFunction(generator); } else { foreach (ConstructorNodeInvocation i in inherit) { i.node.GenerateFunction(generator); } } generator.Resolver.EnterContext(); generator.Resolver.EnterFakeContext(definition); StringBuilder sb = new StringBuilder(); //sb.Append(parentDefinition.TypeReference.TypeName.Data); sb.Append("this"); //sb.Append(definition.TypeReference.TypeName.Data); parameters.PrettyPrint(sb); string name = sb.ToString(); generator.Resolver.CurrentFieldName = name; generator.AllocateAssembler(); parameters.Generate(generator); ParameterMetadata thisParam = parameters.Find("this"); generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference); int thisslot = generator.Resolver.ResolveSlotOffset(new Identifier(location, "this")); generator.Resolver.IncompleteSlot(thisslot, false); statement.Prepare(generator); if (redirect == null) { definition.PrepareInitializer(generator); } generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location); generator.Assembler.StartFunction(); if (redirect != null) { redirect.Call(generator); } else { foreach (ConstructorNodeInvocation i in inherit) { i.Call(generator); } definition.GenerateInitializer(generator); } statement.Generate(generator, null); int slot = generator.Resolver.ResolveSlotOffset(new Identifier(location, "this")); generator.Resolver.RetrieveSlot(location, slot, false); foreach (Field field in definition.Fields) { if (generator.Resolver.IsFieldAssigned(field)) { assignedFields.Add(field); } } generator.Resolver.LeaveFakeContext(); generator.Resolver.LeaveContext(); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "constructor:" + parentDefinition.TypeReference.TypeName.Data + "." + name); functionPointer = generator.Assembler.Region.BaseLocation; }
public override void Generate(Generator generator) { Require.False(generated); Require.True(prepared); generated = true; castFunction = new CallableCastFunction(this); castFunction.Generate(generator); generator.Resolver.EnterContext(); generator.Resolver.SetContextParameters(parametersMetadata); generator.Resolver.CurrentFieldName = name.Data + "()"; if (modifiers.Extern) { string className = ParentDefinition.Name.PrimaryName.Data; if (className == "pluk.base.Array") { string s = ParentDefinition.Name.Data; if (s == "pluk.base.Array<pluk.base.Int>") { className = "pluk.base.Array..pluk.base.Int"; } else if (s == "pluk.base.Array<pluk.base.Bool>") { className = "pluk.base.Array..pluk.base.Bool"; } else if (s == "pluk.base.Array<pluk.base.Byte>") { className = "pluk.base.Array..pluk.base.Byte"; } } string fieldName = name.Data; if (modifiers.ExternMetadata == null) { string namespaceName = ParentDefinition.Name.PrimaryName.Namespace; generator.AllocateAssembler(); parametersMetadata.Generate(generator); ParameterMetadata thisParam = parametersMetadata.Find("this"); generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); generator.Assembler.SetupNativeReturnSpace(); int count = parametersMetadata.NativeArgumentCount(); generator.Assembler.SetupNativeStackFrameArgument(count); parametersMetadata.WriteNative(generator.Assembler); generator.Assembler.CallNative(generator.Importer.FetchImport(namespaceName, className, fieldName), count * 2, true, false); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "method-externed:" + ParentDefinition.Name.Data + "." + name.Data); functionPointer = generator.Assembler.Region.BaseLocation; } else { functionPointer = modifiers.ExternMetadata.Generate(generator, ParentDefinition.Name.PrimaryName, name, returnType, parametersMetadata); } } else { generator.AllocateAssembler(); parametersMetadata.Generate(generator); ParameterMetadata thisParam = parametersMetadata.Find("this"); if (modifiers.Static) { Require.True(thisParam.TypeReference.IsStatic); } generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference); statementMetadata.Prepare(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); JumpToken returnToken = generator.Assembler.CreateJumpToken(); generator.Resolver.RegisterGoto("@return", returnToken); JumpToken recurToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(recurToken); generator.Resolver.RegisterGoto("@recur", recurToken); statementMetadata.Generate(generator, returnType); if (modifiers.Abstract) { generator.Assembler.Empty(); generator.Assembler.CrashIfNull(); } else if ((returnType != null) && (!returnType.IsVoid) && (!statementMetadata.Returns())) { throw new CompilerException(statementMetadata, string.Format(Resource.Culture, Resource.NotAllCodePathsReturnAValue)); } generator.Assembler.SetDestination(returnToken); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "method:" + ParentDefinition.Name.Data + "." + name.Data); functionPointer = generator.Assembler.Region.BaseLocation; } generator.Resolver.LeaveContext(); }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); if (statement.IsEmptyStatement()) { throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody)); } generator.Resolver.EnterContext(); expression.Prepare(generator, null); expression.Generate(generator); // Iterator<slot> ? // create the field, and the hidden enumerator if (enumeratorType == null) { enumeratorType = expression.TypeReference; } else { enumeratorType.GenerateConversion(expression, generator, expression.TypeReference); } generator.Resolver.AddVariable(enumeratorName, enumeratorType, enumeratorSlot, true); generator.Resolver.AssignSlot(enumeratorSlot); // get the enumerator from the expression generator.Assembler.StoreVariable(enumeratorSlot); // start of the loop JumpToken loopToken = generator.Assembler.CreateJumpToken(); generator.Assembler.SetDestination(loopToken); // move the enumerator and check if something is available move.Prepare(generator, null); move.Generate(generator); boolType.GenerateConversion(this, generator, move.TypeReference); JumpToken skipToken = generator.Assembler.CreateJumpToken(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.JumpIfFalse(skipToken); // something is available so put it in the field current.Prepare(generator, null); current.Generate(generator); if (type == null) { type = current.TypeReference; } if (name != null) { generator.Resolver.AddVariable(name, type, slot, true); type.GenerateConversion(this, generator, current.TypeReference); generator.Resolver.AssignSlot(slot); generator.Assembler.StoreVariable(slot); } // for body generator.Resolver.EnterContext(); generator.Resolver.RegisterGoto("@continue", loopToken); generator.Resolver.RegisterGoto("@break", skipToken); statement.Generate(generator, returnType); generator.Resolver.LeaveContext(); generator.Assembler.Jump(loopToken); generator.Assembler.SetDestination(skipToken); generator.Resolver.LeaveContext(); }