Complete rewrite of the symbol resolution API.
- Constants are now symbols alongside variables in the "storable" symbol class. - Added Resolve* and MustResolve* versions in the new symbol-resolution API. - Moved storable-symbol compilation code out of the AST classes and into the respective symbol classes. Storable symbols have extra compile methods for get, set, increment, and decrement operations. - Adapted the scope class accordingly. - Added checks against assignment to constant symbols (which all throw sunAssignConstantException).
This commit is contained in:
parent
664d1e227e
commit
0840a33f9b
7 changed files with 224 additions and 125 deletions
|
@ -124,7 +124,7 @@ namespace arookas
|
||||||
class sunPostfixAugment : sunOperand
|
class sunPostfixAugment : sunOperand
|
||||||
{
|
{
|
||||||
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
||||||
public sunAugment Operator { get { return this[1] as sunAugment; } }
|
public sunAugment Augment { get { return this[1] as sunAugment; } }
|
||||||
|
|
||||||
public sunPostfixAugment(sunSourceLocation location)
|
public sunPostfixAugment(sunSourceLocation location)
|
||||||
: base(location)
|
: base(location)
|
||||||
|
@ -134,19 +134,22 @@ namespace arookas
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var variableInfo = context.ResolveVariable(Variable);
|
var symbol = context.MustResolveStorable(Variable);
|
||||||
|
if (symbol is sunConstantSymbol)
|
||||||
|
{
|
||||||
|
throw new sunAssignConstantException(Variable);
|
||||||
|
}
|
||||||
if (Parent is sunOperand)
|
if (Parent is sunOperand)
|
||||||
{
|
{
|
||||||
context.Text.PushVariable(variableInfo);
|
symbol.CompileGet(context);
|
||||||
}
|
}
|
||||||
Operator.Compile(context, variableInfo);
|
Augment.Compile(context, symbol);
|
||||||
context.Text.StoreVariable(variableInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class sunPrefixAugment : sunOperand
|
class sunPrefixAugment : sunOperand
|
||||||
{
|
{
|
||||||
public sunAugment Operator { get { return this[0] as sunAugment; } }
|
public sunAugment Augment { get { return this[0] as sunAugment; } }
|
||||||
public sunIdentifier Variable { get { return this[1] as sunIdentifier; } }
|
public sunIdentifier Variable { get { return this[1] as sunIdentifier; } }
|
||||||
|
|
||||||
public sunPrefixAugment(sunSourceLocation location)
|
public sunPrefixAugment(sunSourceLocation location)
|
||||||
|
@ -157,12 +160,15 @@ namespace arookas
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var variableInfo = context.ResolveVariable(Variable);
|
var symbol = context.MustResolveStorable(Variable);
|
||||||
Operator.Compile(context, variableInfo);
|
if (symbol is sunConstantSymbol)
|
||||||
context.Text.StoreVariable(variableInfo);
|
{
|
||||||
|
throw new sunAssignConstantException(Variable);
|
||||||
|
}
|
||||||
|
Augment.Compile(context, symbol);
|
||||||
if (Parent is sunOperand)
|
if (Parent is sunOperand)
|
||||||
{
|
{
|
||||||
context.Text.PushVariable(variableInfo);
|
symbol.CompileGet(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +181,7 @@ namespace arookas
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void Compile(sunContext context, sunVariableSymbol variable);
|
public abstract void Compile(sunContext context, sunStorableSymbol symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
class sunIncrement : sunAugment
|
class sunIncrement : sunAugment
|
||||||
|
@ -186,9 +192,10 @@ namespace arookas
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Compile(sunContext context, sunVariableSymbol variable)
|
public override void Compile(sunContext context, sunStorableSymbol symbol)
|
||||||
{
|
{
|
||||||
context.Text.IncVariable(variable);
|
symbol.CompileInc(context);
|
||||||
|
symbol.CompileSet(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,9 +207,10 @@ namespace arookas
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Compile(sunContext context, sunVariableSymbol variable)
|
public override void Compile(sunContext context, sunStorableSymbol symbol)
|
||||||
{
|
{
|
||||||
context.Text.DecVariable(variable);
|
symbol.CompileDec(context);
|
||||||
|
symbol.CompileSet(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace arookas
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var callableInfo = context.ResolveCallable(this);
|
var callableInfo = context.MustResolveCallable(this);
|
||||||
if (!callableInfo.Parameters.ValidateArgumentCount(Arguments.Count))
|
if (!callableInfo.Parameters.ValidateArgumentCount(Arguments.Count))
|
||||||
{
|
{
|
||||||
throw new sunArgumentCountException(this, callableInfo);
|
throw new sunArgumentCountException(this, callableInfo);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
namespace arookas
|
namespace arookas
|
||||||
{
|
{
|
||||||
class sunVariableReference : sunNode
|
class sunStorableReference : sunNode
|
||||||
{
|
{
|
||||||
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
public sunIdentifier Storable { get { return this[0] as sunIdentifier; } }
|
||||||
|
|
||||||
public sunVariableReference(sunSourceLocation location)
|
public sunStorableReference(sunSourceLocation location)
|
||||||
: base(location)
|
: base(location)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -12,23 +12,13 @@
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
sunVariableSymbol variableInfo;
|
context.MustResolveStorable(Storable).Compile(context);
|
||||||
sunConstInfo constInfo;
|
|
||||||
context.ResolveVariableOrConstant(Variable, out variableInfo, out constInfo);
|
|
||||||
if (variableInfo != null)
|
|
||||||
{
|
|
||||||
context.Text.PushVariable(variableInfo);
|
|
||||||
}
|
|
||||||
if (constInfo != null)
|
|
||||||
{
|
|
||||||
constInfo.Expression.Compile(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class sunVariableDeclaration : sunNode
|
class sunVariableDeclaration : sunNode
|
||||||
{
|
{
|
||||||
public sunIdentifier Variable { get { return this[0] as sunIdentifier; } }
|
public sunIdentifier Storable { get { return this[0] as sunIdentifier; } }
|
||||||
|
|
||||||
public sunVariableDeclaration(sunSourceLocation location)
|
public sunVariableDeclaration(sunSourceLocation location)
|
||||||
: base(location)
|
: base(location)
|
||||||
|
@ -38,7 +28,7 @@
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var variableInfo = context.DeclareVariable(Variable);
|
context.DeclareVariable(Storable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +42,7 @@
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var variableInfo = context.DeclareVariable(Variable);
|
context.DeclareVariable(Storable);
|
||||||
base.Compile(context);
|
base.Compile(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,8 +60,12 @@
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var variableInfo = context.ResolveVariable(Variable);
|
var symbol = context.MustResolveStorable(Storable);
|
||||||
Operator.Compile(context, variableInfo, Expression);
|
if (symbol is sunConstantSymbol)
|
||||||
|
{
|
||||||
|
throw new sunAssignConstantException(Storable);
|
||||||
|
}
|
||||||
|
Operator.Compile(context, symbol as sunVariableSymbol, Expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +82,7 @@
|
||||||
|
|
||||||
public override void Compile(sunContext context)
|
public override void Compile(sunContext context)
|
||||||
{
|
{
|
||||||
var constInfo = context.DeclareConstant(Constant, Expression);
|
context.DeclareConstant(Constant, Expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
156
ssc/context.cs
156
ssc/context.cs
|
@ -118,7 +118,7 @@ namespace arookas
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// builtins
|
// callables
|
||||||
public sunBuiltinSymbol DeclareBuiltin(sunBuiltinDeclaration node)
|
public sunBuiltinSymbol DeclareBuiltin(sunBuiltinDeclaration node)
|
||||||
{
|
{
|
||||||
var symbolInfo = SymbolTable.Callables.FirstOrDefault(f => f.Name == node.Builtin.Value);
|
var symbolInfo = SymbolTable.Callables.FirstOrDefault(f => f.Name == node.Builtin.Value);
|
||||||
|
@ -130,22 +130,6 @@ namespace arookas
|
||||||
SymbolTable.Add(builtinInfo);
|
SymbolTable.Add(builtinInfo);
|
||||||
return builtinInfo;
|
return builtinInfo;
|
||||||
}
|
}
|
||||||
public sunBuiltinSymbol DeclareSystemBuiltin(string name, bool variadic, params string[] parameters)
|
|
||||||
{
|
|
||||||
var builtinInfo = SymbolTable.Builtins.FirstOrDefault(f => f.Name == name);
|
|
||||||
if (builtinInfo == null)
|
|
||||||
{
|
|
||||||
builtinInfo = new sunBuiltinSymbol(name, new sunParameterInfo(parameters, variadic), SymbolTable.Count);
|
|
||||||
SymbolTable.Add(builtinInfo);
|
|
||||||
}
|
|
||||||
return builtinInfo;
|
|
||||||
}
|
|
||||||
public sunBuiltinSymbol ResolveSystemBuiltin(string name)
|
|
||||||
{
|
|
||||||
return SymbolTable.Builtins.FirstOrDefault(f => f.Name == name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// functions
|
|
||||||
public sunFunctionSymbol DefineFunction(sunFunctionDefinition node)
|
public sunFunctionSymbol DefineFunction(sunFunctionDefinition node)
|
||||||
{
|
{
|
||||||
if (node.Parameters.IsVariadic)
|
if (node.Parameters.IsVariadic)
|
||||||
|
@ -163,85 +147,123 @@ namespace arookas
|
||||||
}
|
}
|
||||||
public sunCallableSymbol ResolveCallable(sunFunctionCall node)
|
public sunCallableSymbol ResolveCallable(sunFunctionCall node)
|
||||||
{
|
{
|
||||||
var symbolInfo = SymbolTable.Callables.FirstOrDefault(f => f.Name == node.Function.Value);
|
var symbol = SymbolTable.Callables.FirstOrDefault(f => f.Name == node.Function.Value);
|
||||||
if (symbolInfo == null)
|
if (symbol == null)
|
||||||
{
|
{
|
||||||
throw new sunUndefinedFunctionException(node);
|
throw new sunUndefinedFunctionException(node);
|
||||||
}
|
}
|
||||||
return symbolInfo;
|
return symbol;
|
||||||
|
}
|
||||||
|
public sunCallableSymbol MustResolveCallable(sunFunctionCall node)
|
||||||
|
{
|
||||||
|
var symbol = ResolveCallable(node);
|
||||||
|
if (symbol == null)
|
||||||
|
{
|
||||||
|
throw new sunUndefinedFunctionException(node);
|
||||||
|
}
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// variables
|
public sunBuiltinSymbol DeclareSystemBuiltin(string name, bool variadic, params string[] parameters)
|
||||||
|
{
|
||||||
|
var builtinInfo = SymbolTable.Builtins.FirstOrDefault(f => f.Name == name);
|
||||||
|
if (builtinInfo == null)
|
||||||
|
{
|
||||||
|
builtinInfo = new sunBuiltinSymbol(name, new sunParameterInfo(parameters, variadic), SymbolTable.Count);
|
||||||
|
SymbolTable.Add(builtinInfo);
|
||||||
|
}
|
||||||
|
return builtinInfo;
|
||||||
|
}
|
||||||
|
public sunBuiltinSymbol ResolveSystemBuiltin(string name)
|
||||||
|
{
|
||||||
|
return SymbolTable.Builtins.FirstOrDefault(f => f.Name == name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// storables
|
||||||
public sunVariableSymbol DeclareVariable(sunIdentifier node)
|
public sunVariableSymbol DeclareVariable(sunIdentifier node)
|
||||||
{
|
{
|
||||||
// assert variable is not already declared in current scope
|
// assert variable is not already declared in current scope
|
||||||
if (Scopes.Top.GetIsVariableDeclared(node.Value))
|
if (Scopes.Top.GetIsDeclared(node.Value))
|
||||||
{
|
{
|
||||||
throw new sunRedeclaredVariableException(node);
|
throw new sunRedeclaredVariableException(node);
|
||||||
}
|
}
|
||||||
var variableInfo = Scopes.DeclareVariable(node.Value);
|
var variableInfo = Scopes.DeclareVariable(node.Value);
|
||||||
return variableInfo;
|
return variableInfo;
|
||||||
}
|
}
|
||||||
public sunVariableSymbol ResolveVariable(sunIdentifier node)
|
public sunConstantSymbol DeclareConstant(sunIdentifier node, sunExpression expression)
|
||||||
{
|
{
|
||||||
// walk the stack backwards to resolve to the variable's latest declaration
|
if (Scopes.Top.GetIsDeclared(node.Value))
|
||||||
for (int i = Scopes.Count - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
var variableInfo = Scopes[i].ResolveVariable(node.Value);
|
|
||||||
if (variableInfo != null)
|
|
||||||
{
|
|
||||||
return variableInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new sunUndeclaredVariableException(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sunVariableSymbol DeclareParameter(string name) { return Scopes.DeclareVariable(name); }
|
|
||||||
|
|
||||||
// constants
|
|
||||||
public sunConstInfo DeclareConstant(sunIdentifier node, sunExpression expression)
|
|
||||||
{
|
|
||||||
if (Scopes.Top.GetIsConstantDeclared(node.Value))
|
|
||||||
{
|
{
|
||||||
throw new sunRedeclaredVariableException(node);
|
throw new sunRedeclaredVariableException(node);
|
||||||
}
|
}
|
||||||
var constInfo = Scopes.Top.DeclareConstant(node.Value, expression);
|
var constInfo = Scopes.Top.DeclareConstant(node.Value, expression);
|
||||||
return constInfo;
|
return constInfo;
|
||||||
}
|
}
|
||||||
public sunConstInfo ResolveConstant(sunIdentifier node)
|
public sunStorableSymbol ResolveStorable(sunIdentifier node)
|
||||||
{
|
{
|
||||||
// walk the stack backwards to resolve to the constant's latest declaration
|
|
||||||
for (int i = Scopes.Count - 1; i >= 0; --i)
|
for (int i = Scopes.Count - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
var constInfo = Scopes[i].ResolveConstant(node.Value);
|
var symbol = Scopes[i].ResolveStorable(node.Value);
|
||||||
if (constInfo != null)
|
if (symbol != null)
|
||||||
{
|
{
|
||||||
return constInfo;
|
return symbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new sunUndeclaredVariableException(node);
|
return null;
|
||||||
|
}
|
||||||
|
public sunVariableSymbol ResolveVariable(sunIdentifier node)
|
||||||
|
{
|
||||||
|
for (int i = Scopes.Count - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
var symbol = Scopes[i].ResolveVariable(node.Value);
|
||||||
|
if (symbol != null)
|
||||||
|
{
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public sunConstantSymbol ResolveConstant(sunIdentifier node)
|
||||||
|
{
|
||||||
|
for (int i = Scopes.Count - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
var symbol = Scopes[i].ResolveConstant(node.Value);
|
||||||
|
if (symbol != null)
|
||||||
|
{
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public sunStorableSymbol MustResolveStorable(sunIdentifier node)
|
||||||
|
{
|
||||||
|
var symbol = ResolveStorable(node);
|
||||||
|
if (symbol == null)
|
||||||
|
{
|
||||||
|
throw new sunUndeclaredVariableException(node);
|
||||||
|
}
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
public sunVariableSymbol MustResolveVariable(sunIdentifier node)
|
||||||
|
{
|
||||||
|
var symbol = ResolveVariable(node);
|
||||||
|
if (symbol == null)
|
||||||
|
{
|
||||||
|
throw new sunUndeclaredVariableException(node);
|
||||||
|
}
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
public sunConstantSymbol MustResolveConstant(sunIdentifier node)
|
||||||
|
{
|
||||||
|
var symbol = ResolveConstant(node);
|
||||||
|
if (symbol == null)
|
||||||
|
{
|
||||||
|
throw new sunUndeclaredVariableException(node);
|
||||||
|
}
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResolveVariableOrConstant(sunIdentifier node, out sunVariableSymbol variableInfo, out sunConstInfo constInfo)
|
public sunVariableSymbol DeclareParameter(string name) { return Scopes.DeclareVariable(name); }
|
||||||
{
|
|
||||||
variableInfo = null;
|
|
||||||
constInfo = null;
|
|
||||||
// walk the stack backwards to resolve to the latest declaration
|
|
||||||
for (int i = Scopes.Count - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
var variable = Scopes[i].ResolveVariable(node.Value);
|
|
||||||
if (variable != null)
|
|
||||||
{
|
|
||||||
variableInfo = variable;
|
|
||||||
}
|
|
||||||
var constant = Scopes[i].ResolveConstant(node.Value);
|
|
||||||
if (constant != null)
|
|
||||||
{
|
|
||||||
constInfo = constant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new sunUndeclaredVariableException(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteHeader()
|
void WriteHeader()
|
||||||
{
|
{
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace arookas
|
||||||
// variables
|
// variables
|
||||||
switch (GetId(node))
|
switch (GetId(node))
|
||||||
{
|
{
|
||||||
case __sunConstants.VARIABLE_REFERENCE: return new sunVariableReference(location);
|
case __sunConstants.VARIABLE_REFERENCE: return new sunStorableReference(location);
|
||||||
case __sunConstants.VARIABLE_DECLARATION: return new sunVariableDeclaration(location);
|
case __sunConstants.VARIABLE_DECLARATION: return new sunVariableDeclaration(location);
|
||||||
case __sunConstants.VARIABLE_DEFINITION: return new sunVariableDefinition(location);
|
case __sunConstants.VARIABLE_DEFINITION: return new sunVariableDefinition(location);
|
||||||
case __sunConstants.VARIABLE_ASSIGNMENT: return new sunVariableAssignment(location);
|
case __sunConstants.VARIABLE_ASSIGNMENT: return new sunVariableAssignment(location);
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace arookas
|
||||||
class sunScopeStack : IEnumerable<sunScope>
|
class sunScopeStack : IEnumerable<sunScope>
|
||||||
{
|
{
|
||||||
List<sunScope> stack = new List<sunScope>(8);
|
List<sunScope> stack = new List<sunScope>(8);
|
||||||
int GlobalCount { get { return stack.Where(i => i.Type == sunScopeType.Script).Sum(i => i.VariableCount); } }
|
int GlobalCount { get { return stack.Where(i => i.Type == sunScopeType.Script).Sum(i => i.StorableCount); } }
|
||||||
int LocalCount { get { return stack.Where(i => i.Type == sunScopeType.Function).Sum(i => i.VariableCount); } }
|
int LocalCount { get { return stack.Where(i => i.Type == sunScopeType.Function).Sum(i => i.StorableCount); } }
|
||||||
|
|
||||||
public int Count { get { return stack.Count; } }
|
public int Count { get { return stack.Count; } }
|
||||||
|
|
||||||
|
@ -73,8 +73,7 @@ namespace arookas
|
||||||
|
|
||||||
class sunScope
|
class sunScope
|
||||||
{
|
{
|
||||||
List<sunVariableSymbol> variables = new List<sunVariableSymbol>(10);
|
List<sunStorableSymbol> storables = new List<sunStorableSymbol>(10);
|
||||||
List<sunConstInfo> constants = new List<sunConstInfo>(10);
|
|
||||||
public sunScopeType Type { get; private set; }
|
public sunScopeType Type { get; private set; }
|
||||||
|
|
||||||
public sunScope(sunScopeType type)
|
public sunScope(sunScopeType type)
|
||||||
|
@ -82,34 +81,36 @@ namespace arookas
|
||||||
Type = type;
|
Type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int VariableCount { get { return variables.Count; } }
|
public int StorableCount { get { return storables.Count; } }
|
||||||
public int ConstantCount { get { return constants.Count; } }
|
public int VariableCount { get { return storables.OfType<sunVariableSymbol>().Count(); } }
|
||||||
|
public int ConstantCount { get { return storables.OfType<sunConstantSymbol>().Count(); } }
|
||||||
|
|
||||||
|
public bool GetIsDeclared(string name) { return storables.Any(v => v.Name == name); }
|
||||||
|
|
||||||
public bool GetIsVariableDeclared(string name) { return variables.Any(v => v.Name == name); }
|
|
||||||
public sunVariableSymbol DeclareVariable(string name, int display, int index)
|
public sunVariableSymbol DeclareVariable(string name, int display, int index)
|
||||||
{
|
{
|
||||||
if (GetIsVariableDeclared(name) || GetIsConstantDeclared(name))
|
if (GetIsDeclared(name))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var variableInfo = new sunVariableSymbol(name, display, index);
|
var variableInfo = new sunVariableSymbol(name, display, index);
|
||||||
variables.Add(variableInfo);
|
storables.Add(variableInfo);
|
||||||
return variableInfo;
|
return variableInfo;
|
||||||
}
|
}
|
||||||
public sunVariableSymbol ResolveVariable(string name) { return variables.FirstOrDefault(v => v.Name == name); }
|
public sunConstantSymbol DeclareConstant(string name, sunExpression expression)
|
||||||
|
|
||||||
public bool GetIsConstantDeclared(string name) { return constants.Any(c => c.Name == name); }
|
|
||||||
public sunConstInfo DeclareConstant(string name, sunExpression expression)
|
|
||||||
{
|
{
|
||||||
if (GetIsVariableDeclared(name) || GetIsConstantDeclared(name))
|
if (GetIsDeclared(name))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var constInfo = new sunConstInfo(name, expression);
|
var constantSymbol = new sunConstantSymbol(name, expression);
|
||||||
constants.Add(constInfo);
|
storables.Add(constantSymbol);
|
||||||
return constInfo;
|
return constantSymbol;
|
||||||
}
|
}
|
||||||
public sunConstInfo ResolveConstant(string name) { return constants.FirstOrDefault(c => c.Name == name); }
|
|
||||||
|
public sunStorableSymbol ResolveStorable(string name) { return storables.FirstOrDefault(i => i.Name == name); }
|
||||||
|
public sunVariableSymbol ResolveVariable(string name) { return storables.OfType<sunVariableSymbol>().FirstOrDefault(i => i.Name == name); }
|
||||||
|
public sunConstantSymbol ResolveConstant(string name) { return storables.OfType<sunConstantSymbol>().FirstOrDefault(i => i.Name == name); }
|
||||||
}
|
}
|
||||||
|
|
||||||
enum sunScopeType
|
enum sunScopeType
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace arookas
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void Compile(sunContext context);
|
||||||
|
|
||||||
public virtual int WriteSymbolTable(aBinaryWriter writer, int ofs)
|
public virtual int WriteSymbolTable(aBinaryWriter writer, int ofs)
|
||||||
{
|
{
|
||||||
writer.WriteS32((int)Type);
|
writer.WriteS32((int)Type);
|
||||||
|
@ -88,8 +90,6 @@ namespace arookas
|
||||||
|
|
||||||
public abstract void OpenCallSite(sunContext context, int argumentCount);
|
public abstract void OpenCallSite(sunContext context, int argumentCount);
|
||||||
public abstract void CloseCallSites(sunContext context);
|
public abstract void CloseCallSites(sunContext context);
|
||||||
|
|
||||||
public abstract void Compile(sunContext context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class sunBuiltinSymbol : sunCallableSymbol
|
class sunBuiltinSymbol : sunCallableSymbol
|
||||||
|
@ -196,7 +196,35 @@ namespace arookas
|
||||||
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class sunVariableSymbol : sunSymbol
|
abstract class sunStorableSymbol : sunSymbol
|
||||||
|
{
|
||||||
|
protected sunStorableSymbol(string name)
|
||||||
|
: base(name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Compile(sunContext context)
|
||||||
|
{
|
||||||
|
CompileGet(context); // compile get by default
|
||||||
|
}
|
||||||
|
public abstract void CompileGet(sunContext context);
|
||||||
|
public abstract void CompileSet(sunContext context);
|
||||||
|
public virtual void CompileInc(sunContext context)
|
||||||
|
{
|
||||||
|
CompileGet(context);
|
||||||
|
context.Text.PushInt(1);
|
||||||
|
context.Text.Add();
|
||||||
|
}
|
||||||
|
public virtual void CompileDec(sunContext context)
|
||||||
|
{
|
||||||
|
CompileGet(context);
|
||||||
|
context.Text.PushInt(1);
|
||||||
|
context.Text.Sub();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sunVariableSymbol : sunStorableSymbol
|
||||||
{
|
{
|
||||||
public int Display { get; private set; }
|
public int Display { get; private set; }
|
||||||
public int Index { get; private set; }
|
public int Index { get; private set; }
|
||||||
|
@ -214,6 +242,22 @@ namespace arookas
|
||||||
Index = index;
|
Index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void CompileGet(sunContext context)
|
||||||
|
{
|
||||||
|
context.Text.PushVariable(Display, Index);
|
||||||
|
}
|
||||||
|
public override void CompileSet(sunContext context)
|
||||||
|
{
|
||||||
|
context.Text.StoreVariable(Display, Index);
|
||||||
|
}
|
||||||
|
public override void CompileInc(sunContext context)
|
||||||
|
{
|
||||||
|
context.Text.IncVariable(Display, Index);
|
||||||
|
}
|
||||||
|
public override void CompileDec(sunContext context)
|
||||||
|
{
|
||||||
|
context.Text.DecVariable(Display, Index);
|
||||||
|
}
|
||||||
public override int WriteSymbolTable(aBinaryWriter writer, int ofs)
|
public override int WriteSymbolTable(aBinaryWriter writer, int ofs)
|
||||||
{
|
{
|
||||||
base.WriteSymbolTable(writer, ofs);
|
base.WriteSymbolTable(writer, ofs);
|
||||||
|
@ -225,10 +269,40 @@ namespace arookas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class sunConstantSymbol : sunStorableSymbol
|
||||||
|
{
|
||||||
|
sunExpression Expression { get; set; }
|
||||||
|
|
||||||
|
// symbol table
|
||||||
|
public override sunSymbolType Type { get { return sunSymbolType.Constant; } }
|
||||||
|
public override uint Data { get { return 0; } }
|
||||||
|
|
||||||
|
public sunConstantSymbol(string name, sunExpression expression)
|
||||||
|
: base(name)
|
||||||
|
{
|
||||||
|
if (expression == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("expression");
|
||||||
|
}
|
||||||
|
Expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CompileGet(sunContext context)
|
||||||
|
{
|
||||||
|
Expression.Compile(context);
|
||||||
|
}
|
||||||
|
public override void CompileSet(sunContext context)
|
||||||
|
{
|
||||||
|
// checks against this have to be implemented at a higher level
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum sunSymbolType
|
enum sunSymbolType
|
||||||
{
|
{
|
||||||
Builtin,
|
Builtin,
|
||||||
Function,
|
Function,
|
||||||
Variable,
|
Variable,
|
||||||
|
Constant,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue