Example #1
0
        public override void BreakApartParsedTokens()
        {
            SynLog.Log($"Breaking apart type {this.typeName}.");
            SynLog.LogFragments(this.declarationTokens);

            // For struct structname { ... }, remove everything except the ...
            this.declarationTokens.RemoveRange(0, 3);

            int lastIdx = this.declarationTokens.Count - 1;

            if (this.declarationTokens[lastIdx].MatchesSymbol(";"))
            {
                this.declarationTokens.RemoveRange(lastIdx - 1, 2);
            }
            else
            {
                this.declarationTokens.RemoveRange(lastIdx, 1);
            }

            while (this.declarationTokens.Count > 0)
            {
                if (this.declarationTokens[0].MatchesSymbol(";") == true)
                {
                    this.declarationTokens.RemoveAt(0);
                    continue;
                }

                SynRegion rgn = SynRegion.Parse(this, this.declarationTokens);
                if (rgn != null)
                {
                    this.regions.Add(rgn.name, rgn);
                    continue;
                }

                SynFuncDecl fnParse =
                    SynFuncDecl.Parse(
                        this,
                        this.declarationTokens,
                        this.typeName,
                        false,
                        SynFuncDecl.ParseType.StructContext);

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

                SynVarValue varParse = SynVarValue.ParseBodyVar(this.declarationTokens, SynVarValue.OuterScope.Struct);
                if (varParse != null)
                {
                    this.AddVariable(varParse);
                    continue;
                }
            }
        }
Example #2
0
        public SynVarValue AddVariable(string varName, string tyName, VarDst dst, SynVarValue.VarLocation varLoc)
        {
            SynVarValue newVar = new SynVarValue();

            newVar.varLoc   = varLoc;
            newVar.varName  = varName;
            newVar.typeName = tyName;

            this.AddVariable(newVar, dst);
            return(newVar);
        }
Example #3
0
 public void AddVariable(SynVarValue var)
 {
     if (var.varLoc == SynVarValue.VarLocation.Static)
     {
         this.AddGlobalVar(var);
     }
     else
     {
         this.AddLocalVariable(var);
     }
 }
Example #4
0
        SynVarValue GetParamPhrase(List <Token> tokens)
        {
            int idx = 0;

            if (tokens[idx].Matches(TokenType.tyWord, "param") == false)
            {
                return(null);
            }

            if (
                tokens[idx + 1].Matches(TokenType.tyWord) == false ||
                tokens[idx + 2].Matches(TokenType.tyWord) == false)
            {
                throw new System.Exception($"Error parsing param on line {tokens[idx].line}");
            }

            string typename = tokens[idx + 1].fragment;
            string varname  = tokens[idx + 2].fragment;

            if (this.varLookups.ContainsKey(varname) == true)
            {
                throw new System.Exception($"Redefining variable {varname} on line {tokens[idx].line}.");
            }

            SynVarValue newParam = new SynVarValue();

            newParam.typeName = typename;
            newParam.varName  = varname;
            newParam.varLoc   = SynVarValue.VarLocation.Parameter;

            idx = 3;
            if (tokens[idx].Matches(TokenType.tySymbol, "=") == true)
            {
                ++idx;
                Parser.MovePastScopeTSemi(ref idx, tokens);
            }
            else if (tokens[idx].Matches(TokenType.tySymbol, ";") == false)
            {
                throw new System.Exception($"Unexpected end to param {varname} on line {tokens[idx].line}.");
            }

            List <Token> declPhrase = tokens.GetRange(0, idx);

            tokens.RemoveRange(0, idx);

            newParam.declPhrase = declPhrase;

            this.AddVariable(newParam);

            return(newParam);
        }
Example #5
0
 public void AddVariable(SynVarValue var, VarDst dst)
 {
     if (dst == VarDst.Global)
     {
         this.globalLookups.Add(var.varName, var);
         this.globalDefs.Add(var);
     }
     else if (dst == VarDst.Local)
     {
         this.varLookups.Add(var.varName, var);
         this.varDefs.Add(var);
     }
     else
     {
         throw new SynthExceptionImpossible("Attemping to add variable to unknown destination");
     }
 }
Example #6
0
 public void AddGlobalVar(SynVarValue var)
 {
     this.AddVariable(var, VarDst.Global);
 }
Example #7
0
 public void AddLocalVariable(SynVarValue var)
 {
     this.AddVariable(var, VarDst.Local);
 }
Example #8
0
        /// <summary>
        /// This function is expected to be called during AST construction
        /// (of whatever needs the copy constructor). This means struct
        /// processing and alignment should have already occured. This also
        /// means the function will be queued for being constructed into
        /// WASM binary like all other functions in a later pass.
        /// </summary>
        /// <param name="autocreate">If the function doesn't exist, auto
        /// create a default copy constructor and register it with the struct.
        /// </param>
        /// <returns>The found, or created, copy constructor for the struct.</returns>
        public override SynFuncDecl GetCopyConstructor(bool autocreate, SynNestingBuilder scb)
        {
            List <SynFuncDecl> lstFns;

            if (this.functions.TryGetValue(this.typeName, out lstFns) == false)
            {
                if (autocreate == false)
                {
                    return(null);
                }

                // If we're autocreating, prepare a list for it to be registered in.
                lstFns = new List <SynFuncDecl>();
                this.functions.Add(this.typeName, lstFns);
            }
            else
            {
                foreach (SynFuncDecl fns in lstFns)
                {
                    if (fns.returnType != null)
                    {
                        continue;
                    }

                    if (fns.parameterSet.Count != 2)
                    {
                        continue;
                    }

                    if (
                        fns.parameterSet.Get(0).type != this ||
                        fns.parameterSet.Get(1).type != this)
                    {
                        continue;
                    }

                    return(fns);
                }

                if (autocreate == false)
                {
                    return(null);
                }
            }

            SynFuncDecl sfdCC = new SynFuncDecl(this);
            //
            SynVarValue svvDst = new SynVarValue();

            svvDst.varLoc   = SynVarValue.VarLocation.ThisRef;
            svvDst.dataType = SynVarValue.VarValueDataType.Pointer;
            //
            SynVarValue svvSrc = new SynVarValue();

            svvSrc.varLoc   = SynVarValue.VarLocation.Parameter;
            svvSrc.dataType = SynVarValue.VarValueDataType.Reference;

            sfdCC.parameterSet.AddParameter(svvDst);
            sfdCC.parameterSet.AddParameter(svvSrc);

            // TODO: Do explicit alignment here?

            // Add this ahead of time
            lstFns.Add(sfdCC);

            // Go through each variable in order and copy them by producing the proper AST
            for (int i = 0; i < this.varDefs.Count; ++i)
            {
                SynVarValue svv = this.varDefs[i];    // The member to copy

                if (svv.type.intrinsic == true)
                {
                    AST astSrcDeref     = new AST(new Token(-1, svv.varName, TokenType.tyWord), scb, ASTOp.DerefName, null, svv.type, false, AST.DataManifest.Procedural, 0);
                    AST astSrcGetMember = new AST(new Token(), scb, ASTOp.GetMemberVar, svvSrc, this, false, AST.DataManifest.Procedural, 0, astSrcDeref);

                    AST astDstDeref     = new AST(new Token(-1, svv.varName, TokenType.tyWord), scb, ASTOp.DerefName, null, svv.type, false, AST.DataManifest.Procedural, 0);
                    AST astDstGetMember = new AST(new Token(), scb, ASTOp.GetMemberVar, svvSrc, this, false, AST.DataManifest.Procedural, 0, astSrcDeref);

                    AST astSetVar = new AST(new Token(), scb, ASTOp.SetValue, null, null, false, AST.DataManifest.NoData, 0, astSrcDeref, astSrcGetMember);
                    sfdCC.ast.branches.Add(astSetVar);
                }
                else
                {
                    // Else, it's a sub-struct, and we use GetCopyConstructor() recursively
                    // to copy it.
                    throw new SynthExceptionCompile("Class copy constructors are not supported.");
                }
            }

            return(sfdCC);
        }
Example #9
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.");
        }