public static SynStruct Parse(SynScope parentScope, List <Token> tokens) { if (tokens[0].Matches(TokenType.tyWord, "struct") == false) { return(null); } // TODO: Check that the name is available if (tokens[1].Matches(TokenType.tyWord) == false) { throw new SynthExceptionSyntax(tokens[1], "Missing struct name."); } if (tokens[2].Matches(TokenType.tySymbol, "{") == false) { throw new SynthExceptionSyntax(tokens[2], "Missing struct body entry."); } int idx = 2; Parser.MovePastScopeTSemi(ref idx, tokens); SynStruct ret = new SynStruct(parentScope, tokens[0].fragment); ret.typeName = tokens[1].fragment; ret.declarationTokens = tokens.GetRange(0, idx); tokens.RemoveRange(0, idx); ret.BreakApartParsedTokens(); return(ret); }
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."); }