public void LeaveFakeContext() { Require.Assigned(currentDefinition); Require.Assigned(savedDefinition); currentDefinition = savedDefinition; savedDefinition = null; }
public void EnterFakeContext(Definition definition) { Require.Assigned(definition); Require.Assigned(currentDefinition); Require.Unassigned(savedDefinition); savedDefinition = currentDefinition; currentDefinition = definition; }
public void Setup(Context parent, bool parentReadOnly) { this.parent = parent; this.parentReadOnly = parentReadOnly; if (parentReadOnly) { Require.Assigned(parent); } }
public void SetImplicitFields(int slot, TypeReference type) { Require.Assigned(type); Require.Unassigned(implicitSlot); implicitSlot = new ImplicitField(); implicitSlot.slot = slot; implicitSlot.type = type; AssignSlot(slot); ReadSlot(slot); }
public void WritePlaceholderDisplacement32(Placeholder target) { Require.Assigned(target); RegionPlaceholder placeholder; placeholder.offset = stream.Position; placeholder.target = target; placeholder.targetRef = null; placeholder.relative = false; placeholder.relativeSection = false; placeholder.relativeFile = false; placeholder.displacement32 = true; WriteInt32(0); placeholder.location = CurrentLocation; placeholders.Add(placeholder); }
private RegionPlaceholder SetupPlaceholderRef(PlaceholderRef target) { Require.Assigned(target); RegionPlaceholder placeholder; placeholder.offset = stream.Position; placeholder.target = new Placeholder(); placeholder.targetRef = target; placeholder.relative = false; placeholder.relativeSection = false; placeholder.relativeFile = false; placeholder.displacement32 = false; WriteNumber(0); placeholder.location = CurrentLocation; return(placeholder); }
public void AddVariable(Identifier name, TypeReference type, int slot, bool readOnly) { Require.Assigned(name); Require.Assigned(type); if (variables.ContainsKey(name.Data)) { throw new CompilerException(name, string.Format(Resource.Culture, Resource.VariableWithThatNameAlreadyDefined, name.Data)); } Entry e = new Entry(); e.id = name.Data; e.name = name; e.slot = slot; e.type = type; e.readOnly = readOnly; variables.Add(name.Data, e); varBySlot.Add(slot, e); }
private TypeReference InnerResolveType(ILocation location, TypeName type, bool throwIfNoMatch) { Require.Assigned(location); if (type.IsFunction || !type.HasNamespace || (type.TemplateParameters.Count > 0)) { if (localResolveCache.ContainsKey(type.Data)) { TypeReference t = localResolveCache[type.Data]; if ((t != null) || (!throwIfNoMatch)) { return(t); } } } else { if (resolveCache.ContainsKey(type.Data)) { TypeReference t = resolveCache[type.Data]; if ((t != null) || (!throwIfNoMatch)) { return(t); } } } TypeReference result; TypeName original = type; if (type.Nullable) { result = InnerResolveType(location, new TypeName(type, Nullability.NotNullable), throwIfNoMatch); } else { if (type.IsFunction) { result = type.ResolveFunctionType(this); } else { if (type.HasNamespace) { if (type.TemplateParameters.Count > 0) { TypeName resolvedInnerName = new TypeName(type.PrimaryName); resolvedInnerName.SetHasNamespace(); foreach (TypeName templateParameter in type.TemplateParameters) { TypeReference t = InnerResolveType(templateParameter, templateParameter, throwIfNoMatch); if ((!throwIfNoMatch) && (t == null)) { return(null); } if (t.TypeName.Data.StartsWith("MapBucket")) { t = InnerResolveType(templateParameter, templateParameter, throwIfNoMatch); throw new Exception("boom"); } resolvedInnerName.AddTemplateParameter(t.TypeName); } type = resolvedInnerName; } LoadType(type); if ((!store.HasDefinition(type)) && store.HasTemplateDefinition(type)) { List <TypeReference> parameters = new List <TypeReference>(); foreach (TypeName templateParameter in type.TemplateParameters) { TypeReference t = InnerResolveType(templateParameter, templateParameter, throwIfNoMatch); if ((!throwIfNoMatch) && (t == null)) { return(null); } parameters.Add(t); } store.InstantiateTemplate(type, parameters); } result = ResolveTypeFullyQualified(location, type, throwIfNoMatch); } else { if (type.TemplateParameters.Count > 0) { TypeName outerType = new TypeName(type.PrimaryName); foreach (TypeName innerName in type.TemplateParameters) { TypeReference t = InnerResolveType(location, innerName, throwIfNoMatch); if ((!throwIfNoMatch) && (t == null)) { return(null); } outerType.AddTemplateParameter(t.TypeName); } type = outerType; } if (imports.Count == 0) { imports.Put(""); // when no imports are found, assume baseline system } if (!imports.Contains("pluk.base")) { imports.Put("pluk.base"); // this may seem silly, bit if we come here recursively this avoids a concurrent modifiecation assertion } result = null; foreach (string ns in imports) { TypeName fullname = type.Prefix(ns); result = InnerResolveType(location, fullname, false); if (result != null) { type = fullname; break; } } if (result == null) { if (throwIfNoMatch) { throw new CompilerException(location, string.Format(Resource.Culture, Resource.NoDefinitionForType, type.DataModifierLess)); } } } } } if (original.Nullable && (!original.IsVoid) && (result != null)) { result = new NullableTypeReference(result, new TypeName(result.TypeName, Nullability.ExplicitNullable)); } if (result != null) { resolveCache[result.TypeName.Data] = result; } if ((result == null) || original.IsFunction || !original.HasNamespace || (original.TemplateParameters.Count > 0)) { localResolveCache[original.Data] = result; } else { resolveCache[original.Data] = result; } return(result); }
public void SetContextParameters(Parameters parameters) { Require.Assigned(parameters); Require.Unassigned(contextParameters); contextParameters = parameters; }
public void RetrieveSlot(ILocation location, int slot, bool allowIncomplete) { bool incomplete = false; foreach (Context context in contexts) { if (context.variableIncomplete.ContainsKey(slot)) { if (allowIncomplete) { return; } if (context.variableIncomplete[slot]) { return; } incomplete = true; break; } } bool written = false; if (!incomplete) { foreach (Context context in contexts) { if (context.variableRead.ContainsKey(slot)) { return; } } foreach (Context context in contexts) { if (context.variableWrite.ContainsKey(slot)) { written = true; break; } } } Context.Entry entry = null; foreach (Context context in contexts) { foreach (Context.Entry v in context.variables.Values) { if (v.slot == slot) { entry = v; break; } } } foreach (Context context in contexts) { if (context.variableIncomplete.ContainsKey(slot)) { incomplete = true; break; } } Require.Assigned(entry); if (incomplete) { if (entry.type.IsDefinition) { Definition d = ((DefinitionTypeReference)entry.type).Definition; if (d.CheckAllFieldsAssigned(location, this, true)) { IncompleteSlot(slot, true); return; } } throw new CompilerException(location, string.Format(Resource.Culture, Resource.ObjectNotFullyAssigned, entry.name.Data)); } else { if (written) { contexts.Peek().ReadSlot(slot); } else { throw new CompilerException(location, string.Format(Resource.Culture, Resource.VariableMightNotBeAssigned, entry.name.Data)); } } }
public Opera_nd_tor(OperatorDefinition operatorDef, Expression expression) { Require.Assigned(operatorDef); this.operatorDef = operatorDef; this.postfixExpression = expression; }
public Opera_nd_tor(OperatorDefinition operatorDef, ParserToken token) { Require.Assigned(operatorDef); this.operatorDef = operatorDef; this.token = token; }
public Placeholder(Region region, long offset) { Require.Assigned(region); this.region = region; this.offset = offset; }
static int Main(string[] args) { try { List <string> types = new List <string>(); Set <string> paths = new Set <string>(); List <string> files = new List <string>(); Set <string> hiddenPaths = new Set <string>(); bool noDefaultPaths = false; bool path = false; bool noMoreFlags = false; bool showPathAndFiles = false; bool hiddenPath = false; bool breakOnStart = false; bool showUsedTypes = false; bool noEntryPoint = false; foreach (string s in args) { bool file = path || noMoreFlags; if (!file) { if (s == "-m:l64") { if (Windows_x86 || Linux_x86 || Windows_x86_64 || Linux_x86_64) { throw new Exception("Only one platform can be used at a time."); } linux_x86_64 = true; } else if (s == "-m:l32") { if (Windows_x86 || Linux_x86 || Windows_x86_64 || Linux_x86_64) { throw new Exception("Only one platform can be used at a time."); } linux_x86 = true; } else if (s == "-m:w64") { if (Windows_x86 || Linux_x86 || Windows_x86_64 || Linux_x86_64) { throw new Exception("Only one platform can be used at a time."); } windows_x86_64 = true; } else if (s == "-m:w32") { if (Windows_x86 || Linux_x86 || Windows_x86_64 || Linux_x86_64) { throw new Exception("Only one platform can be used at a time."); } windows_x86 = true; } else if (s == "-p") { path = true; } else if (s == "-ndp") { noDefaultPaths = true; } else if (s == "-x:v") { Console.WriteLine("Version " + version); } else if (s == "-x:ns") { stackTrace = false; } else if (s == "-x:s") { stackTrace = true; } else if (s == "-a:v") { allowUnreadAndUnusedVariablesFieldsAndExpressions = true; } else if (s == "-x:nf") { suppressPathInErrors = true; } else if (s == "-x:p") { showPathAndFiles = true; } else if (s == "-x:f") { writeFileNameOnRead = true; } else if (s == "-x:fnc") { caseSensitive = false; } else if (s == "-x:fc") { caseSensitive = true; } else if (s == "-x:b") { breakOnStart = true; } else if (s == "-x:t") { showUsedTypes = true; } else if (s == "-x:e") { noEntryPoint = true; } else if (s == "-p:h") { path = true; hiddenPath = true; } else if (s == "--") { noMoreFlags = true; } else { file = true; } } if (file) { if (path) { if (hiddenPath) { hiddenPaths.Put(Path.GetFullPath(s)); } else { paths.Put(Path.GetFullPath(s)); } } else if (s.Contains(".pluk")) { files.Add(Path.GetFullPath(s)); } else { types.Add(s); } path = false; hiddenPath = false; } } if (!noDefaultPaths) { string env_pluk_source = Environment.GetEnvironmentVariable("PLUK_SOURCES"); if (!string.IsNullOrEmpty(env_pluk_source)) { paths.Put(Path.GetFullPath(env_pluk_source)); } paths.Put(Path.GetFullPath(".")); foreach (string p in hiddenPaths) { paths.Put(p); } } if (showPathAndFiles) { foreach (string type in types) { Console.WriteLine("type: " + type); } foreach (string file in files) { Console.WriteLine("file: " + file); } foreach (string vpath in paths) { Console.WriteLine("path: " + vpath); } } if (!(Windows_x86 || Linux_x86 || Windows_x86_64 || Linux_x86_64)) { if (Environment.OSVersion.Platform == PlatformID.Unix) { if (IntPtr.Size == 8) { linux_x86_64 = true; } else if (IntPtr.Size == 4) { linux_x86 = true; } else { throw new ArgumentOutOfRangeException("unsupported pointer width: " + IntPtr.Size); } } else { // if (IntPtr.Size == 8) // windows_x86_64 = true; // else if (IntPtr.Size == 4) windows_x86 = true; // else // throw new ArgumentOutOfRangeException("unsupported pointer width: " + IntPtr.Size); } } if ((types.Count == 0) && (files.Count == 0)) { throw new ArgumentException(string.Format(Resource.Culture, Resource.CompilerUsage, AppDomain.CurrentDomain.FriendlyName)); } types.Add("pluk.base.String"); types.Add("pluk.base.Int"); types.Add("pluk.base.Float"); types.Add("pluk.base.Bool"); types.Add("pluk.base.StaticString"); types.Add("pluk.base.Object"); types.Add("pluk.base.Application"); types.Add("pluk.base.OverflowException"); types.Add("pluk.base.BoundsException"); if (paths.Count == 0) { paths.Add(Path.GetFullPath(".")); } Generator generator = null; if (Linux_x86_64) { generator = new Compiler.Binary.LinuxELF64X86_64.Generator(paths, !CaseSensitiveFileSystem); } if (Linux_x86) { generator = new Compiler.Binary.LinuxELF32X86.Generator(paths, !CaseSensitiveFileSystem); } if (Windows_x86) { generator = new Compiler.Binary.WinPE32X86.Generator(paths, !CaseSensitiveFileSystem); } Require.Assigned(generator); try { string baseClass = null; if (files.Count == 0) { baseClass = types[0]; } foreach (string file in files) { string typename = generator.Resolver.ParseFile(file); if (baseClass == null) { baseClass = typename; } } generator.SetModuleName(baseClass); foreach (string type in types) { TypeName tn = new TypeName(new Identifier(new NowhereLocation(), type)); tn.SetHasNamespace(); generator.Resolver.ResolveType(new NowhereLocation(), tn); } TypeName baseClassType = new TypeName(new Identifier(new NowhereLocation(), baseClass)); baseClassType.SetHasNamespace(); if (noEntryPoint) { ResolveBaseTypes(generator); generator.Resolver.ResolveEverything(generator); generator.Resolver.PrepareEverything(generator); generator.Resolver.GenerateEverything(generator); } else { ResolveBaseTypes(generator); generator.Resolver.ResolveEverything(generator); Definition t = generator.Resolver.ResolveDefinitionType(new NowhereLocation(), baseClassType).Definition; generator.Resolver.PrepareEverything(generator); generator.Resolver.GenerateEverything(generator); CheckHelper.SetupExceptionHandlers(generator); DefinitionTypeReference applicationType = generator.Resolver.ResolveDefinitionType(new NowhereLocation(), new TypeName(new Identifier(new NowhereLocation(), "pluk.base.Application"))); if (!t.Supports(applicationType)) { throw new CompilerException(t, string.Format(Resource.Culture, Resource.ClassHasNoMain, baseClass)); } generator.AllocateAssembler(); Assembler g = generator.Assembler; if (breakOnStart) { g.Break(); } g.StackRoot(); g.CallNative(generator.SaveStackRoot, 1, false, false); g.StartFunction(); // setup basic types in pluk_base.dll SetupBaseTypes(generator); //reset floating point mask generator.Assembler.SetupFpu(); generator.Resolver.CallStaticInitializers(generator); //Instance program object and call the main method g.LoadMethodStruct(t.FindConstructor(new NowhereLocation(), new FunctionTypeReference(new NowhereLocation(), t.TypeReference, new List <TypeReference>()), applicationType.Definition).RuntimeStruct); g.PushValue(); Placeholder retSite = g.CallFromStack(0); generator.AddCallTraceEntry(retSite, new NowhereLocation(), "", "entrypoint"); Method m = t.FindMethod(new Identifier(new NowhereLocation(), "MainIndirect"), false, null, applicationType.Definition, true); g.FetchMethod(t.GetMethodOffset(new NowhereLocation(), m, applicationType.Definition)); g.PushValue(); retSite = g.CallFromStack(0); generator.AddCallTraceEntry(retSite, new NowhereLocation(), "", "entrypoint"); // todo, provide argument g.Empty(); g.PushValue(); g.PopNativeArgument(); g.CallNative(generator.Exit, 2, false, false); g.StopFunction(); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "entryPoint:" + baseClass + ".Main"); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "_start"); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "main"); generator.WriteToFile(g.Region); } if (showUsedTypes) { foreach (Definition def in generator.Definitions) { Console.WriteLine("Definition: " + def.Name.DataModifierLess); } } } finally { generator.Dispose(); } } catch (CompilerException ce) { if (stackTrace) { Console.Error.WriteLine(ce.ToString()); } else if (suppressPathInErrors) { Console.Error.WriteLine(ce.Error); } else { Console.Error.WriteLine(ce.ErrorMessage); } return(1); } catch (Exception e) { if (stackTrace) { Console.Error.WriteLine(e.ToString()); } else { Console.Error.WriteLine(e.Message); } return(255); } return(0); }