WIP - simple example compiles

This commit is contained in:
Andrew Noyes 2019-09-09 22:56:19 -07:00
parent 94668c6f1f
commit eeb2da5c9d
4 changed files with 61 additions and 21 deletions

View File

@ -1207,3 +1207,18 @@ TEST_CASE("/fdbrpc/flow/wait_expression_after_cancel")
ASSERT( a == 1 );
return Void();
}
class Foo {
public:
explicit Foo(int x) : x(x) {}
Future<int> foo() { return fooActor(this); }
ACTOR static Future<int> fooActor(Foo* self);
private:
int x;
};
ACTOR Future<int> Foo::fooActor(Foo* self) {
wait(Future<Void>());
return self->x;
}

View File

@ -213,7 +213,6 @@ namespace actorcompiler
public void Write(TextWriter writer, out int lines)
{
lines = 0;
//if (isTopLevel) writer.WriteLine("namespace {");
writer.WriteLine(memberIndentStr + "template<> struct Descriptor<struct {0}> {{", descr.name);
writer.WriteLine(memberIndentStr + "\tstatic StringRef typeName() {{ return LiteralStringRef(\"{0}\"); }}", descr.name);
@ -265,7 +264,6 @@ namespace actorcompiler
lines++;
}
//if (isTopLevel) writer.WriteLine("}"); // namespace
}
}
@ -276,7 +274,6 @@ namespace actorcompiler
string sourceFile;
List<StateVar> state;
List<CallbackVar> callbacks = new List<CallbackVar>();
bool isTopLevel;
const string loopDepth0 = "int loopDepth=0";
const string loopDepth = "int loopDepth";
const int codeIndent = +2;
@ -287,12 +284,11 @@ namespace actorcompiler
string This;
bool generateProbes;
public ActorCompiler(Actor actor, string sourceFile, bool isTopLevel, bool lineNumbersEnabled, bool generateProbes)
public ActorCompiler(Actor actor, string sourceFile, bool lineNumbersEnabled, bool generateProbes)
{
this.actor = actor;
this.sourceFile = sourceFile;
this.isTopLevel = isTopLevel;
this.LineNumbersEnabled = lineNumbersEnabled;
this.LineNumbersEnabled = false;
this.generateProbes = generateProbes;
FindState();
@ -302,21 +298,13 @@ namespace actorcompiler
string fullReturnType =
actor.returnType != null ? string.Format("Future<{0}>", actor.returnType)
: "void";
if (actor.isForwardDeclaration) {
foreach (string attribute in actor.attributes) {
writer.Write(attribute + " ");
}
if (actor.isStatic) writer.Write("static ");
writer.WriteLine("{0} {3}{1}( {2} );", fullReturnType, actor.name, string.Join(", ", ParameterList()), actor.nameSpace==null ? "" : actor.nameSpace + "::");
return;
}
for (int i = 0; ; i++)
{
className = string.Format("{0}{1}Actor{2}",
actor.name.Substring(0, 1).ToUpper(),
actor.name.Substring(1),
i!=0 ? i.ToString() : "");
if (usedClassNames.Add(className))
if (actor.isForwardDeclaration || usedClassNames.Add(className))
break;
}
@ -326,6 +314,18 @@ namespace actorcompiler
stateClassName = className + "State";
var fullStateClassName = stateClassName + GetTemplateActuals(new VarDeclaration { type = "class", name = fullClassName });
if (actor.isForwardDeclaration) {
foreach (string attribute in actor.attributes) {
writer.Write(attribute + " ");
}
if (actor.isStatic) writer.Write("static ");
writer.WriteLine("{0} {3}{1}( {2} );", fullReturnType, actor.name, string.Join(", ", ParameterList()), actor.nameSpace==null ? "" : actor.nameSpace + "::");
if (actor.enclosingClass.Length > 0) {
writer.WriteLine("template <class> friend class {0};", stateClassName);
}
return;
}
var body = getFunction("", "body", loopDepth0);
var bodyContext = new Context {
target = body,
@ -353,8 +353,6 @@ namespace actorcompiler
}
bodyContext.catchFErr.WriteLine("loopDepth = 0;");
if (isTopLevel) writer.WriteLine("namespace {");
// The "State" class contains all state and user code, to make sure that state names are accessible to user code but
// inherited members of Actor, Callback etc are not.
writer.WriteLine("// This generated class is to be used only via {0}()", actor.name);
@ -399,7 +397,6 @@ namespace actorcompiler
//WriteStartFunc(body, writer);
WriteCancelFunc(writer);
writer.WriteLine("};");
if (isTopLevel) writer.WriteLine("}"); // namespace
WriteTemplate(writer);
LineNumber(writer, actor.SourceLine);
foreach (string attribute in actor.attributes) {

View File

@ -255,6 +255,11 @@ namespace actorcompiler
//showTokens();
}
class ClassContext {
public string name;
public int inBlocks;
}
public void Write(System.IO.TextWriter writer, string destFileName)
{
writer.NewLine = "\n";
@ -266,6 +271,7 @@ namespace actorcompiler
outLine++;
}
int inBlocks = 0;
Stack<ClassContext> classContextStack = new Stack<ClassContext>();
for(int i=0; i<tokens.Length; i++)
{
if(tokens[0].SourceLine == 0)
@ -276,9 +282,10 @@ namespace actorcompiler
{
int end;
var actor = ParseActor(i, out end);
actor.enclosingClass = classContextStack.Count > 0 ? classContextStack.Peek().name : "";
var actorWriter = new System.IO.StringWriter();
actorWriter.NewLine = "\n";
new ActorCompiler(actor, sourceFile, inBlocks==0, LineNumbersEnabled, generateProbes).Write(actorWriter);
new ActorCompiler(actor, sourceFile, LineNumbersEnabled, generateProbes).Write(actorWriter);
string[] actorLines = actorWriter.ToString().Split('\n');
bool hasLineNumber = false;
@ -322,10 +329,29 @@ namespace actorcompiler
outLine++;
}
}
else if (tokens[i].Value == "class" || tokens[i].Value == "struct")
{
writer.Write(tokens[i].Value);
var toks = range(i+1, tokens.Length).SkipWhile(Whitespace);
if (!toks.IsEmpty)
{
classContextStack.Push(new ClassContext{name = toks.First().Value, inBlocks = inBlocks });
}
}
else
{
if (tokens[i].Value == "{") inBlocks++;
else if (tokens[i].Value == "}") inBlocks--;
if (tokens[i].Value == "{")
{
inBlocks++;
}
else if (tokens[i].Value == "}")
{
inBlocks--;
if (classContextStack.Count > 0 && classContextStack.Peek().inBlocks == inBlocks)
{
classContextStack.Pop();
}
}
writer.Write(tokens[i].Value);
outLine += tokens[i].Value.Count(c => c == '\n');
}

View File

@ -226,6 +226,8 @@ namespace actorcompiler
public List<string> attributes = new List<string>();
public string returnType;
public string name;
// "" if there is not enclosing class
public string enclosingClass;
public VarDeclaration[] parameters;
public VarDeclaration[] templateFormals; //< null if not a template
public CodeBlock body;