Changed how call sites are opened/closed.

Now builtin symbols also have call sites. I had to move the call-site
property out of the base class because builtins need to store
argument-count information as well.
This commit is contained in:
arookas 2016-01-31 21:26:51 -05:00
parent b2330dfa6c
commit b0ad55a005

View file

@ -51,14 +51,12 @@ namespace arookas {
abstract class sunCallableSymbol : sunSymbol { abstract class sunCallableSymbol : sunSymbol {
public sunParameterInfo Parameters { get; private set; } public sunParameterInfo Parameters { get; private set; }
protected List<sunPoint> CallSites { get; private set; }
public bool HasCallSites { get { return CallSites.Count > 0; } } public abstract bool HasCallSites { get; }
protected sunCallableSymbol(string name, sunParameterInfo parameterInfo) protected sunCallableSymbol(string name, sunParameterInfo parameterInfo)
: base(name) { : base(name) {
Parameters = parameterInfo; Parameters = parameterInfo;
CallSites = new List<sunPoint>(10);
} }
public abstract void OpenCallSite(sunCompiler compiler, int argumentCount); public abstract void OpenCallSite(sunCompiler compiler, int argumentCount);
@ -66,33 +64,77 @@ namespace arookas {
} }
class sunBuiltinSymbol : sunCallableSymbol { class sunBuiltinSymbol : sunCallableSymbol {
public int Index { get; private set; } int mIndex;
List<sunBuiltinCallSite> mCallSites;
public int Index {
get { return mIndex; }
set { mIndex = value; }
}
public override bool HasCallSites {
get { return mCallSites.Count > 0; }
}
// symbol table // symbol table
public override sunSymbolType Type { get { return sunSymbolType.Builtin; } } public override sunSymbolType Type { get { return sunSymbolType.Builtin; } }
public override uint Data { get { return (uint)Index; } } public override uint Data { get { return (uint)Index; } }
public sunBuiltinSymbol(string name, int index) public sunBuiltinSymbol(string name, int index)
: base(name, null) { : this(name, null, index) { }
Index = index;
}
public sunBuiltinSymbol(string name, sunParameterInfo parameters, int index) public sunBuiltinSymbol(string name, sunParameterInfo parameters, int index)
: base(name, parameters) { : base(name, parameters) {
Index = index; mIndex = index;
mCallSites = new List<sunBuiltinCallSite>(10);
} }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
// don't compile builtins // don't compile builtins
} }
public override void OpenCallSite(sunCompiler compiler, int argumentCount) { public override void OpenCallSite(sunCompiler compiler, int argumentCount) {
compiler.Binary.WriteFUNC(Index, argumentCount); var callSite = new sunBuiltinCallSite(compiler.Binary.OpenPoint(), argumentCount);
mCallSites.Add(callSite);
compiler.Binary.WriteFUNC(0, 0); // dummy
}
public override void CloseCallSites(sunCompiler compiler) {
compiler.Binary.Keep();
foreach (var callSite in mCallSites) {
compiler.Binary.Goto(callSite.Point);
compiler.Binary.WriteFUNC(mIndex, callSite.ArgCount);
}
compiler.Binary.Back();
}
struct sunBuiltinCallSite {
sunPoint mPoint;
int mArgCount;
public sunPoint Point {
get { return mPoint; }
}
public int ArgCount {
get { return mArgCount; }
}
public sunBuiltinCallSite(sunPoint point, int argCount) {
mPoint = point;
mArgCount = argCount;
}
} }
public override void CloseCallSites(sunCompiler compiler) { }
} }
class sunFunctionSymbol : sunCallableSymbol { class sunFunctionSymbol : sunCallableSymbol {
sunNode Body { get; set; } uint mOffset;
public uint Offset { get; private set; } sunNode mBody;
List<sunPoint> mCallSites;
public uint Offset {
get { return mOffset; }
}
public override bool HasCallSites {
get { return mCallSites.Count > 0; }
}
// symbol table // symbol table
public override sunSymbolType Type { get { return sunSymbolType.Function; } } public override sunSymbolType Type { get { return sunSymbolType.Function; } }
@ -100,28 +142,32 @@ namespace arookas {
public sunFunctionSymbol(string name, sunParameterInfo parameters, sunNode body) public sunFunctionSymbol(string name, sunParameterInfo parameters, sunNode body)
: base(name, parameters) { : base(name, parameters) {
Body = body; if (body == null) {
throw new ArgumentNullException("body");
}
mCallSites = new List<sunPoint>(5);
mBody = body;
} }
public override void Compile(sunCompiler compiler) { public override void Compile(sunCompiler compiler) {
Offset = compiler.Binary.Offset; mOffset = compiler.Binary.Offset;
compiler.Context.Scopes.Push(sunScopeType.Function); compiler.Context.Scopes.Push(sunScopeType.Function);
compiler.Context.Scopes.ResetLocalCount(); compiler.Context.Scopes.ResetLocalCount();
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(Body.MaxLocalCount); compiler.Binary.WriteMKFR(mBody.MaxLocalCount);
Body.Compile(compiler); mBody.Compile(compiler);
compiler.Binary.WriteRET0(); compiler.Binary.WriteRET0();
compiler.Context.Scopes.Pop(); compiler.Context.Scopes.Pop();
} }
public override void OpenCallSite(sunCompiler compiler, int argumentCount) { public override void OpenCallSite(sunCompiler compiler, int argumentCount) {
var point = compiler.Binary.WriteCALL(argumentCount); var point = compiler.Binary.WriteCALL(argumentCount);
CallSites.Add(point); mCallSites.Add(point);
} }
public override void CloseCallSites(sunCompiler compiler) { public override void CloseCallSites(sunCompiler compiler) {
foreach (var callSite in CallSites) { foreach (var callSite in mCallSites) {
compiler.Binary.ClosePoint(callSite, Offset); compiler.Binary.ClosePoint(callSite, Offset);
} }
} }