From 1b514eecff234b96ebf1b8912c4b19c3853b6d76 Mon Sep 17 00:00:00 2001 From: arookas Date: Mon, 28 Dec 2015 02:47:49 -0500 Subject: [PATCH] Made variable-packing optional. --- ssc/context.cs | 24 ++++++++++++++++++++++-- ssc/scope stack.cs | 28 ++++++++++++++++++++++++++-- ssc/symbol table.cs | 3 ++- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/ssc/context.cs b/ssc/context.cs index 99bc4d7..a71b8de 100644 --- a/ssc/context.cs +++ b/ssc/context.cs @@ -180,16 +180,36 @@ namespace arookas // storables public sunVariableSymbol DeclareVariable(sunIdentifier node) { - // assert variable is not already declared in current scope +#if SSC_RESOLVEVAR_NEST if (Scopes.Top.GetIsDeclared(node.Value)) +#else + if (Scopes.Any(i => i.GetIsDeclared(node.Value))) +#endif { throw new sunRedeclaredVariableException(node); } - return Scopes.DeclareVariable(node.Value); + var symbol = Scopes.DeclareVariable(node.Value); + if (Scopes.Top.Type == sunScopeType.Script) // global-scope variables are added to the symbol table + { +#if SSC_RESOLVEVAR_NEST + // only add the variable symbol if there isn't one with this index already + if (!SymbolTable.Variables.Any(i => i.Index == symbol.Index)) + { + SymbolTable.Add(new sunVariableSymbol(String.Format("global{0}", symbol.Index), symbol.Display, symbol.Index)); + } +#else + SymbolTable.Add(symbol); +#endif + } + return symbol; } public sunConstantSymbol DeclareConstant(sunIdentifier node, sunExpression expression) { +#if SSC_RESOLVEVAR_NEST if (Scopes.Top.GetIsDeclared(node.Value)) +#else + if (Scopes.Any(i => i.GetIsDeclared(node.Value))) +#endif { throw new sunRedeclaredVariableException(node); } diff --git a/ssc/scope stack.cs b/ssc/scope stack.cs index c44240d..903f363 100644 --- a/ssc/scope stack.cs +++ b/ssc/scope stack.cs @@ -9,8 +9,13 @@ namespace arookas List Stack { get; set; } public int Count { get { return Stack.Count; } } +#if SSC_PACK_VARS int GlobalCount { get { return Stack.Where(i => i.Type == sunScopeType.Script).Sum(i => i.VariableCount); } } int LocalCount { get { return Stack.Where(i => i.Type == sunScopeType.Function).Sum(i => i.VariableCount); } } +#else + int GlobalCount { get; set; } + int LocalCount { get; set; } +#endif public sunScope Root { get { return this.FirstOrDefault(i => i.Type == Top.Type); } } public sunScope Script { get { return this.FirstOrDefault(i => i.Type == sunScopeType.Script); } } @@ -42,6 +47,11 @@ namespace arookas Push(sunScopeType.Script); // add global scope } +#if !SSC_PACK_VARS + public void ResetGlobalCount() { GlobalCount = 0; } + public void ResetLocalCount() { LocalCount = 0; } +#endif + public sunVariableSymbol DeclareVariable(string name) { switch (Top.Type) @@ -57,11 +67,25 @@ namespace arookas } sunVariableSymbol DeclareGlobal(string name) { - return Top.DeclareVariable(name, 0, GlobalCount); + var symbol = Top.DeclareVariable(name, 0, GlobalCount); +#if !SSC_PACK_VARS + if (symbol != null) + { + ++GlobalCount; + } +#endif + return symbol; } sunVariableSymbol DeclareLocal(string name) { - return Top.DeclareVariable(name, 1, LocalCount); + var symbol = Top.DeclareVariable(name, 1, LocalCount); +#if !SSC_PACK_VARS + if (symbol != null) + { + ++LocalCount; + } +#endif + return symbol; } public IEnumerator GetEnumerator() { return Stack.GetEnumerator(); } diff --git a/ssc/symbol table.cs b/ssc/symbol table.cs index c6f9568..f4d65e7 100644 --- a/ssc/symbol table.cs +++ b/ssc/symbol table.cs @@ -140,9 +140,10 @@ namespace arookas { Offset = context.Text.Offset; context.Scopes.Push(sunScopeType.Function); + context.Scopes.ResetLocalCount(); foreach (var parameter in Parameters) { - context.Scopes.DeclareVariable(parameter); + context.Scopes.DeclareVariable(parameter); // since there is no AST node for these, they won't affect MaxLocalCount } context.Text.StoreDisplay(1); context.Text.DeclareLocal(Body.MaxLocalCount);