Example #1
0
        /// <summary>
        /// Ensure the structs have byte alignments calculated, and that every
        /// member variable type that's referenced is known.
        /// </summary>
        /// <returns></returns>
        public virtual TypeConsolidate ResolveStaticTypeAlignments()
        {
            // contained by value.
            int alreadyDet = 0;
            int newlyDet   = 0;

            foreach (KeyValuePair <string, SynType> kvp in this.typesDefs)
            {
                TypeConsolidate tc = kvp.Value.ResolveStaticTypeAlignments();

                if (tc == TypeConsolidate.AllDetermined)
                {
                    ++alreadyDet;
                }
                else if (tc == TypeConsolidate.UndeterminedProgress)
                {
                    ++newlyDet;
                }
            }

            if (alreadyDet + newlyDet == this.typesDefs.Count)
            {
                return(TypeConsolidate.AllDetermined);
            }
            else if (newlyDet > 0)
            {
                return(TypeConsolidate.UndeterminedProgress);
            }
            else
            {
                return(TypeConsolidate.UndeterminedNoChange);
            }
        }
Example #2
0
        public override TypeConsolidate ResolveStaticTypeAlignments()
        {
            if (resolvedAlignments == true)
            {
                return(TypeConsolidate.AllDetermined);
            }

            int alreadyAligned = 0;
            int newlyAligned   = 0;

            foreach (var v in this.varDefs)
            {
                if (v.type == null)
                {
                    if (string.IsNullOrEmpty(v.typeName) == true)
                    {
                        throw new System.Exception("Unknown type.");
                    }

                    v.type = this.GetType(v.typeName);
                }

                if (v.type.Aligned() == false)
                {
                    ++alreadyAligned;
                    continue;
                }

                TypeConsolidate tc = v.type.ResolveStaticTypeAlignments();
                if (tc == TypeConsolidate.AllDetermined)
                {
                    ++newlyAligned;
                    continue;
                }

                if (tc == TypeConsolidate.UndeterminedProgress)
                {
                    return(TypeConsolidate.UndeterminedProgress);
                }
            }

            if (alreadyAligned + newlyAligned < this.varDefs.Count)
            {
                if (newlyAligned == 0)
                {
                    return(TypeConsolidate.UndeterminedNoChange);
                }
                else
                {
                    return(TypeConsolidate.UndeterminedProgress);
                }
            }

            // All the Type references should now be set - so before we
            // lookup the offsets, we're going to make sure the struct isn't
            // containing itself, or a child member that's containing
            // itself.
            HashSet <string> typesOfChildren = new HashSet <string>();

            this.RegisterContainedValueTypes(typesOfChildren);
            if (typesOfChildren.Contains(this.typeName) == true)
            {
                throw new SynthExceptionCompile($"Datatype {this.typeName} found to contain recursive instances of itself as a child member.");
            }

            int alignment = 0;

            foreach (var v in this.varDefs)
            {
                v.alignmentOffset = alignment;
                alignment        += v.type.GetByteSize();
            }
            this.byteSize = alignment;

            this.resolvedAlignments = true;
            return(TypeConsolidate.AllDetermined);
        }
Example #3
0
        public void ParseContext(List <Token> tokens)
        {
            SynLog.LogHeader("Starting Parse Content");
            SynLog.Log("\tTokens:");
            SynLog.Log(tokens);

            //      Get param globals first
            //
            //////////////////////////////////////////////////
            while (tokens.Count > 0)
            {
                SynVarValue parsedParam = SynVarValue.ParseExposedParam(tokens);
                if (parsedParam == null)
                {
                    break;
                }

                this.AddVariable(parsedParam);
            }

            //      Parse Sections
            //
            //////////////////////////////////////////////////
            int idx = 0;

            while (tokens.Count > 0)
            {
                // Get rid of stray parenthesis
                if (tokens[idx].Matches(TokenType.tySymbol, ";") == true)
                {
                    tokens.RemoveAt(0);
                    continue;
                }

                // Struct parsing
                if (tokens[0].Matches(TokenType.tyWord, "struct") == true)
                {
                    SynStruct sst = SynStruct.Parse(this, tokens);
                    if (sst != null)
                    {
                        this.AddType(sst);
                        continue;
                    }
                }

                // Function parsing
                if (tokens[0].Matches(TokenType.tyWord, "entry") == true)
                {
                    SynFuncDecl sfd = SynFuncDecl.Parse(this, tokens, "", true, SynFuncDecl.ParseType.Entry);
                    sfd.callType = SynFuncDecl.CallType.Entry;

                    if (sfd != null)
                    {
                        this.AddFunction(sfd);
                        continue;
                    }
                    else
                    {
                        throw new System.Exception("entry keyword not part of valid function.");
                    }
                }

                SynFuncDecl synthFn =
                    SynFuncDecl.Parse(
                        this, tokens,
                        "",
                        true,
                        SynFuncDecl.ParseType.RootContext);

                if (synthFn != null)
                {
                    this.AddFunction(synthFn);
                    continue;
                }

                SynVarValue synthVar = SynVarValue.ParseBodyVar(tokens, SynVarValue.OuterScope.Global);
                if (synthVar != null)
                {
                    this.AddVariable(synthVar);
                    continue;
                }

                throw new System.Exception("Unknown token while parsing root context.");
            }

            //      Verify Structs
            //
            //////////////////////////////////////////////////
            SynLog.LogHeader("Verifying types");

            while (true)
            {
                TypeConsolidate tc = this.ResolveStaticTypeAlignments();
                if (tc == TypeConsolidate.UndeterminedNoChange)
                {
                    throw new System.Exception("Could not resolve all types");
                }

                if (tc == TypeConsolidate.AllDetermined)
                {
                    break;
                }
            }

            SynLog.Log("Finished verifying struct successfully.");

            //      Gathering globals
            //
            //////////////////////////////////////////////////
            SynLog.LogHeader("Gathering globals");

            List <SynVarValue> globals = new List <SynVarValue>();

            foreach (SynScope s in this.EnumerateScopes())
            {
                s.RegisterGlobals(globals);
            }

            this.totalGlobalBytes = 0;
            foreach (SynVarValue svv in globals)
            {
                svv.alignmentOffset = this.totalGlobalBytes;

                int byteSz = svv.type.GetByteSize();
                if (byteSz <= 0)
                {
                    throw new SynthExceptionImpossible("Data type for global variable is zero in size.");
                }

                SynLog.Log($"Added {svv.varName} to globals at offset {svv.alignmentOffset}");

                this.totalGlobalBytes += byteSz;
            }

            SynLog.Log($"Total global variable space is {this.totalGlobalBytes}.");

            //      Verify Functions
            //
            //////////////////////////////////////////////////
            SynLog.LogHeader("Verifying After function and variable collection pass.");
            this.Validate_AfterTypeAlignment(0);

            SynLog.Log("Finished verifying functions successfully.");
        }