public override void GenerateConversion(ILocation location, Generator generator, TypeReference value) { if (value is NullableTypeReference) { parent.GenerateConversion(location, generator, ((NullableTypeReference)value).Parent); } else { if (value.TypeName.Data != "void") { parent.GenerateConversion(location, generator, value); } } }
public override void Generate(Generator generator) { base.Generate(generator); condition.Generate(generator); // boolean boolType.GenerateConversion(this, generator, condition.TypeReference); JumpToken elseToken = generator.Assembler.CreateJumpToken(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.JumpIfFalse(elseToken); left.Generate(generator); resultType.GenerateConversion(this, generator, left.TypeReference); JumpToken skipElseToken = generator.Assembler.CreateJumpToken(); generator.Assembler.Jump(skipElseToken); generator.Assembler.SetDestination(elseToken); right.Generate(generator); resultType.GenerateConversion(this, generator, right.TypeReference); generator.Assembler.SetDestination(skipElseToken); }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); if (returnType == null) { throw new CompilerException(this, string.Format(Resource.Culture, Resource.ReturnStatementNotAllowed)); } expression.Prepare(generator, returnType); expression.Generate(generator); returnType.GenerateConversion(this, generator, expression.TypeReference); DoReturn(this, generator); }
public override void Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); Parameters scopeParameters = generator.Resolver.CurrentContextParameters(); Require.Assigned(scopeParameters); if (scopeParameters.ParameterList.Count != this.parameters.Count) { throw new CompilerException(this, string.Format(Resource.Culture, Resource.FunctionCallParameterCountMismatch, ParameterListString(scopeParameters.ParameterList), this.parameters.Count)); } int i = 0; foreach (Expression parameter in this.parameters) { TypeReference tr = scopeParameters.ParameterList[i].TypeReference; parameter.Prepare(generator, tr); i++; } i = 0; foreach (Expression parameter in this.parameters) { TypeReference tr = scopeParameters.ParameterList[i].TypeReference; parameter.Generate(generator); tr.GenerateConversion(this, generator, parameter.TypeReference); i++; generator.Assembler.PushValue(); } generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); //store in local slots List <ParameterMetadata> p = new List <ParameterMetadata>(scopeParameters.ParameterList); p.Reverse(); foreach (ParameterMetadata parameter in p) { generator.Assembler.PopValue(); generator.Assembler.StoreVariable(parameter.Slot); } bool tryContext; JumpToken gotoToken = generator.Resolver.FindGoto("@recur", out tryContext); if ((gotoToken == null) || tryContext) { throw new CompilerException(this, string.Format(Resource.Culture, Resource.UnsupportedJumpOutOfTry)); } generator.Assembler.Jump(gotoToken); }
public override void Generate(Generator generator) { base.Generate(generator); parent.Generate(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); TypeReference ptr = parent.TypeReference; TypeReference str = returnType; if (str.SupportsImplicit(ptr)) { returnType.GenerateConversion(this, generator, parent.TypeReference); } else { JumpToken jtNull = null; jtNull = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfUnassigned(jtNull); generator.Assembler.TypeConversionDynamicNotNull(resolvedType.Id); generator.Assembler.SetDestination(jtNull); } }
public override void Generate(Generator generator) { base.Generate(generator); left.Generate(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); TypeReference leftType = left.TypeReference; if (call == null) { JumpToken skip = generator.Assembler.CreateJumpToken(); generator.Assembler.JumpIfTrue(skip); right.Generate(generator); leftType.GenerateConversion(this, generator, right.TypeReference); generator.Assembler.SetDestination(skip); } else { call.Generate(generator); } }
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, TypeReference returnType) { base.Generate(generator, returnType); generator.Resolver.EnterContext(); expression.Prepare(generator, typeRef); if (typeName == null) { typeRef = expression.TypeReference; } if (!disposable.Supports(typeRef)) { throw new CompilerException(this, Resource.CanOnlyUseScopeOnNotNullDisposable); } expression.Generate(generator); typeRef.GenerateConversion(this, generator, expression.TypeReference); generator.Resolver.AddVariable(name, typeRef, slot, true); generator.Resolver.AssignSlot(slot); generator.Assembler.StoreVariable(slot); statement.Generate(generator, returnType); returns = statement.Returns(); generator.Resolver.LeaveAndMergeContext(); }
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 Placeholder Generate(Generator generator, Identifier primaryContextName, Identifier methodName, TypeReference returnType, Parameters parametersMetadata) { if (string.IsNullOrEmpty(xml)) { generator.AllocateAssembler(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName); generator.Assembler.CallNative(generator.Importer.FetchImport(primaryContextName.Namespace, primaryContextName.Data, methodName.Data), 0, false, true); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "extern:" + primaryContextName.Data + "." + methodName.Data); return(generator.Assembler.Region.BaseLocation); } else { generator.AllocateAssembler(); parametersMetadata.Generate(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName); generator.Assembler.StartFunction(); if (parametersMetadata.ParameterList.Count != parameters.Count) { throw new ExternException(this, "Parameter count mismatch."); } string word = "int32"; if (Program.Linux_x86_64 || Program.Windows_x86_64) { word = "int64"; } generator.Assembler.SetupNativeReturnSpace(); for (int i = parameters.Count - 1; i >= 0; --i) { string type = parameters[i]; if (type == word) { generator.Assembler.RetrieveVariable(parametersMetadata.ParameterList[i].Slot); generator.Assembler.PushValuePart(); } else { throw new ExternException(this, "Unsupported type."); } } if (string.IsNullOrEmpty(library)) { throw new ExternException(this, "No library specified"); } if (string.IsNullOrEmpty(entrypoint)) { throw new ExternException(this, "No entrypoint specified"); } generator.Assembler.CallNative(generator.Importer.FetchImportAsPointer(library, entrypoint), parameters.Count, false, false); if (returns == word) { generator.Assembler.SetTypePart(intType.RuntimeStruct); returnType.GenerateConversion(this, generator, intType); } else if (returns == "void") { voidType.GenerateConversion(this, generator, returnType); generator.Assembler.Empty(); } else { throw new ExternException(this, "Unsupported return type."); } generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "extern:" + primaryContextName.Data + "." + methodName.Data); return(generator.Assembler.Region.BaseLocation); } }
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(); }
public override void Generate(Generator generator) { base.Generate(generator); if (target == null) { int slot = generator.Resolver.ResolveSlotOffset(name); value.Generate(generator); type.GenerateConversion(this, generator, value.TypeReference); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Resolver.WriteSlot(this, slot); generator.Assembler.StoreVariable(slot); } else { target.Generate(generator); TypeReference thisType = target.TypeReference; bool staticRef = thisType is StaticTypeReference; Definition thisDefinition; if (staticRef) { thisDefinition = ((StaticTypeReference)thisType).Parent.Definition; } else { thisDefinition = ((DefinitionTypeReference)thisType).Definition; } if (thisDefinition.HasField(name, staticRef)) { Field field = thisDefinition.GetField(name, staticRef); if (!field.GetModifiers.Static) { generator.Assembler.PushValue(); int fieldOffset = thisDefinition.GetFieldOffset(this, name, generator.Resolver.CurrentDefinition, true); if (target is IIncompleteSlotAssignment) { if (((IIncompleteSlotAssignment)target).IsIncompleteSlot()) { generator.Resolver.AssignField(field); } } value.Generate(generator); type.GenerateConversion(value, generator, value.TypeReference); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); TypeReference slot = field.TypeReference; if (slot.IsNullable) { slot = ((NullableTypeReference)slot).Parent; } DefinitionTypeReference dtr = slot as DefinitionTypeReference; if ((dtr != null) && (!dtr.Definition.GarbageCollectable)) { generator.Assembler.StoreInFieldOfSlotNoTouch(fieldOffset); } else { generator.Assembler.StoreInFieldOfSlot(generator.Toucher, fieldOffset); } } else { generator.Assembler.PushValue(); if (target is IIncompleteSlotAssignment) { if (((IIncompleteSlotAssignment)target).IsIncompleteSlot()) { generator.Resolver.AssignField(field); } } value.Generate(generator); type.GenerateConversion(value, generator, value.TypeReference); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.Store(field.StaticSlot); } } else { int propertySlot = thisDefinition.GetSetPropertyOffset(this, name, generator.Resolver.CurrentDefinition); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.FetchMethod(propertySlot); generator.Assembler.PushValue(); value.Generate(generator); type.GenerateConversion(value, generator, value.TypeReference); generator.Assembler.PushValue(); Placeholder retSite = generator.Assembler.CallFromStack(1); generator.AddCallTraceEntry(retSite, this, generator.Resolver.CurrentDefinition.Name.DataModifierLess, generator.Resolver.CurrentFieldName); } } }