Got rid of scopes (for now)

The remnants of the previous sub-scope implementation is now hidden
behind a dummy preprocessor symbol. I don't know if I'll add it back,
but it'll at least be a while. The byte code and symbol table just don't
like it.
This commit is contained in:
arookas 2016-02-05 01:52:56 -05:00
parent 8ff73fe0f4
commit 9749b81452
6 changed files with 104 additions and 27 deletions

View file

@ -49,8 +49,9 @@ namespace arookas {
public bool IsBranch { get { return Count > 0; } } public bool IsBranch { get { return Count > 0; } }
public bool IsLeaf { get { return Count < 1; } } public bool IsLeaf { get { return Count < 1; } }
public int MaxLocalCount { public int LocalCount {
get { get {
#if SSC_SCOPES
var locals = 0; var locals = 0;
var maxChildLocals = 0; var maxChildLocals = 0;
foreach (var child in this) { foreach (var child in this) {
@ -58,16 +59,28 @@ namespace arookas {
++locals; ++locals;
} }
else if (child is sunCompoundStatement) { else if (child is sunCompoundStatement) {
locals += child.MaxLocalCount; // HACK: compound statements aren't their own scope locals += child.LocalCount; // HACK: compound statements aren't their own scope
} }
else if (!(child is sunFunctionDefinition)) { // don't recurse into function bodies else if (!(child is sunFunctionDefinition)) { // don't recurse into function bodies
var childLocals = child.MaxLocalCount; var childLocals = child.LocalCount;
if (childLocals > maxChildLocals) { if (childLocals > maxChildLocals) {
maxChildLocals = childLocals; maxChildLocals = childLocals;
} }
} }
} }
return locals + maxChildLocals; return locals + maxChildLocals;
#else
var locals = 0;
foreach (var child in this) {
if (child is sunVariableDeclaration || child is sunVariableDefinition) {
++locals;
}
else if (!(child is sunFunctionDefinition)) { // don't recurse into function bodies
locals += child.LocalCount;
}
}
return locals;
#endif
} }
} }

View file

@ -99,7 +99,9 @@ namespace arookas {
: base(location) { } : base(location) { }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
#if SSC_SCOPES
compiler.Context.Scopes.Push(); compiler.Context.Scopes.Push();
#endif
var loop = PushLoop(compiler.Context); var loop = PushLoop(compiler.Context);
TryCompile(Declaration, compiler); TryCompile(Declaration, compiler);
var bodyPrologue = compiler.Binary.OpenPoint(); var bodyPrologue = compiler.Binary.OpenPoint();
@ -112,7 +114,9 @@ namespace arookas {
compiler.Binary.ClosePoint(bodyEpilogue); compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint(); loop.BreakPoint = compiler.Binary.OpenPoint();
compiler.Context.Loops.Pop(compiler); compiler.Context.Loops.Pop(compiler);
#if SSC_SCOPES
compiler.Context.Scopes.Pop(); compiler.Context.Scopes.Pop();
#endif
} }
} }
class sunForDeclaration : sunNode { class sunForDeclaration : sunNode {

View file

@ -9,9 +9,13 @@
: base(location) { } : base(location) { }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
#if SSC_SCOPES
compiler.Context.Scopes.Push(compiler.Context.Scopes.Top.Type); compiler.Context.Scopes.Push(compiler.Context.Scopes.Top.Type);
#endif
base.Compile(compiler); base.Compile(compiler);
#if SSC_SCOPES
compiler.Context.Scopes.Pop(); compiler.Context.Scopes.Pop();
#endif
} }
} }

View file

@ -102,7 +102,11 @@ namespace arookas {
if (symbol == null) { if (symbol == null) {
throw new sunRedeclaredVariableException(node); throw new sunRedeclaredVariableException(node);
} }
if (Scopes.Top.Type == sunScopeType.Script) { // global-scope variables are added to the symbol table #if SSC_SCOPES
if (Scopes.Top.Type == sunScopeType.Script) {
#else
if (Scopes.Count == 1) {
#endif
SymbolTable.Add(symbol); SymbolTable.Add(symbol);
} }
return symbol; return symbol;

View file

@ -5,12 +5,15 @@ using System.Linq;
namespace arookas { namespace arookas {
class sunScopeStack : IEnumerable<sunScope> { class sunScopeStack : IEnumerable<sunScope> {
List<sunScope> mStack; List<sunScope> mStack;
int mGlobals, mLocals; #if SSC_SCOPES
int mLocals;
#endif
public int Count { public int Count {
get { return mStack.Count; } get { return mStack.Count; }
} }
#if SSC_SCOPES
public sunScope Root { public sunScope Root {
get { return this.FirstOrDefault(i => i.Type == Top.Type); } get { return this.FirstOrDefault(i => i.Type == Top.Type); }
} }
@ -20,6 +23,7 @@ namespace arookas {
public sunScope Function { public sunScope Function {
get { return this.FirstOrDefault(i => i.Type == sunScopeType.Function); } get { return this.FirstOrDefault(i => i.Type == sunScopeType.Function); }
} }
#endif
public sunScope Top { public sunScope Top {
get { return this[Count - 1]; } get { return this[Count - 1]; }
} }
@ -30,48 +34,69 @@ namespace arookas {
public sunScopeStack() { public sunScopeStack() {
mStack = new List<sunScope>(8); mStack = new List<sunScope>(8);
#if SSC_SCOPES
Push(sunScopeType.Script); // push global scope Push(sunScopeType.Script); // push global scope
#else
Push();
#endif
} }
public void Push() { Push(Top.Type); } public void Push() {
#if SSC_SCOPES
Push(Top.Type);
#else
mStack.Add(new sunScope());
#endif
}
#if SSC_SCOPES
public void Push(sunScopeType type) { public void Push(sunScopeType type) {
mStack.Add(new sunScope(type)); mStack.Add(new sunScope(type));
} }
public void Pop() { #endif
public void Pop(sunCompiler compiler) {
if (Count > 1) { if (Count > 1) {
#if SSC_SCOPES
if (Top.Type == sunScopeType.Script) {
mLocals = 0; // left the function, reset locals
}
#else
// close relocations while we still have references to the symbols
foreach (var variable in Top) {
variable.CloseRelocations(compiler);
}
#endif
mStack.RemoveAt(Count - 1); mStack.RemoveAt(Count - 1);
} }
} }
public void Clear() { public void Clear() {
mStack.Clear(); mStack.Clear();
#if SSC_SCOPES
Push(sunScopeType.Script); // add global scope Push(sunScopeType.Script); // add global scope
mGlobals = 0;
mLocals = 0;
}
public void ResetGlobalCount() {
mGlobals = 0;
}
public void ResetLocalCount() {
mLocals = 0; mLocals = 0;
#else
Push();
#endif
} }
public sunVariableSymbol DeclareVariable(string name) { public sunVariableSymbol DeclareVariable(string name) {
#if SSC_SCOPES
switch (Top.Type) { switch (Top.Type) {
case sunScopeType.Script: return DeclareGlobal(name); case sunScopeType.Script: return DeclareGlobal(name);
case sunScopeType.Function: return DeclareLocal(name); case sunScopeType.Function: return DeclareLocal(name);
} }
return null; return null;
#else
return Top.DeclareVariable(name, Count - 1, Top.VariableCount);
#endif
} }
public sunConstantSymbol DeclareConstant(string name, sunExpression expression) { public sunConstantSymbol DeclareConstant(string name, sunExpression expression) {
return Top.DeclareConstant(name, expression); return Top.DeclareConstant(name, expression);
} }
#if SSC_SCOPES
sunVariableSymbol DeclareGlobal(string name) { sunVariableSymbol DeclareGlobal(string name) {
var symbol = Top.DeclareVariable(name, 0, mGlobals); // symbol's display/index will be
if (symbol != null) { // filled out by the relocation code
++mGlobals; return Top.DeclareVariable(name, 0, 0);
}
return symbol;
} }
sunVariableSymbol DeclareLocal(string name) { sunVariableSymbol DeclareLocal(string name) {
var symbol = Top.DeclareVariable(name, 1, mLocals); var symbol = Top.DeclareVariable(name, 1, mLocals);
@ -80,6 +105,7 @@ namespace arookas {
} }
return symbol; return symbol;
} }
#endif
public IEnumerator<sunScope> GetEnumerator() { public IEnumerator<sunScope> GetEnumerator() {
return mStack.GetEnumerator(); return mStack.GetEnumerator();
@ -91,15 +117,25 @@ namespace arookas {
class sunScope : IEnumerable<sunStorableSymbol> { class sunScope : IEnumerable<sunStorableSymbol> {
List<sunStorableSymbol> mStorables; List<sunStorableSymbol> mStorables;
#if SSC_SCOPES
sunScopeType mType; sunScopeType mType;
#endif
#if SSC_SCOPES
public sunScopeType Type { public sunScopeType Type {
get { return mType; } get { return mType; }
} }
#endif
#if SSC_SCOPES
public sunScope(sunScopeType type) { public sunScope(sunScopeType type) {
#else
public sunScope() {
#endif
mStorables = new List<sunStorableSymbol>(10); mStorables = new List<sunStorableSymbol>(10);
#if SSC_SCOPES
mType = type; mType = type;
#endif
} }
public int StorableCount { public int StorableCount {
@ -151,8 +187,10 @@ namespace arookas {
} }
} }
#if SSC_SCOPES
enum sunScopeType { enum sunScopeType {
Script, // outside of a function Script,
Function, // inside of a function Function,
} }
#endif
} }

View file

@ -50,6 +50,17 @@ namespace arookas {
mSymbols.Clear(); mSymbols.Clear();
} }
public IEnumerable<sunSymbol> Get() {
return mSymbols;
}
public IEnumerable<TSymbol> Get<TSymbol>() where TSymbol : sunSymbol {
return mSymbols.OfType<TSymbol>();
}
public int GetCount<TSymbol>() where TSymbol : sunSymbol {
return mSymbols.Count(i => i is TSymbol);
}
public IEnumerator<sunSymbol> GetEnumerator() { public IEnumerator<sunSymbol> GetEnumerator() {
return mSymbols.GetEnumerator(); return mSymbols.GetEnumerator();
} }
@ -187,16 +198,19 @@ namespace arookas {
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
mOffset = compiler.Binary.Offset; mOffset = compiler.Binary.Offset;
#if SSC_SCOPES
compiler.Context.Scopes.Push(sunScopeType.Function); compiler.Context.Scopes.Push(sunScopeType.Function);
compiler.Context.Scopes.ResetLocalCount(); #else
compiler.Context.Scopes.Push();
#endif
foreach (var parameter in Parameters) { foreach (var parameter in Parameters) {
compiler.Context.Scopes.DeclareVariable(parameter); // since there is no AST node for these, they won't affect MaxLocalCount compiler.Context.Scopes.DeclareVariable(parameter); // since there is no AST node for these, they won't affect MaxLocalCount
} }
compiler.Binary.WriteMKDS(1); compiler.Binary.WriteMKDS(1);
compiler.Binary.WriteMKFR(mBody.MaxLocalCount); compiler.Binary.WriteMKFR(mBody.LocalCount);
mBody.Compile(compiler); mBody.Compile(compiler);
compiler.Binary.WriteRET0(); compiler.Binary.WriteRET0();
compiler.Context.Scopes.Pop(); compiler.Context.Scopes.Pop(compiler);
++mCompiles; ++mCompiles;
} }
public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) { public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) {