Commit 29ac7b5e authored by Travis Hance's avatar Travis Hance

teach eval to read locals (wip)

parent a09bcba9
......@@ -207,8 +207,8 @@ public:
if (usage->forced_globals.count(name))
return true;
if (name.c_str() != name.c_str())
usage->dump();
if (usesNameLookup)
return false;
return usage->written.count(name) == 0 && usage->got_from_closure.count(name) == 0;
}
bool refersToClosure(InternedString name) override {
......@@ -219,7 +219,7 @@ public:
}
bool saveInClosure(InternedString name) override {
// HAX
if (isCompilerCreatedName(name))
if (isCompilerCreatedName(name) || usesNameLookup)
return false;
return usage->referenced_from_nested.count(name) != 0;
}
......@@ -228,15 +228,14 @@ public:
// HAX
if (isCompilerCreatedName(name))
return VarScopeType::FAST;
if (refersToGlobal(name))
return VarScopeType::GLOBAL;
if (refersToClosure(name))
return VarScopeType::DEREF;
if (usesNameLookup)
return VarScopeType::NAME;
if (refersToGlobal(name))
return VarScopeType::GLOBAL;
if (saveInClosure(name))
return VarScopeType::CLOSURE;
if (usesNameLookup)
return VarScopeType::NAME;
return VarScopeType::FAST;
}
......
......@@ -1102,6 +1102,22 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
return v.o ? v.o : None;
}
Box* astInterpretFunctionEval(CompiledFunction* cf, BoxedDict* locals) {
++cf->times_called;
ASTInterpreter interpreter(cf);
for (const auto& p : locals->d) {
assert(p.first->cls == str_cls);
auto name = static_cast<BoxedString*>(p.first)->s;
InternedString interned = cf->clfunc->source->getInternedStrings().get(name);
interpreter.addSymbol(interned, p.second, false);
}
interpreter.initArguments(0, NULL, NULL, NULL, NULL, NULL, NULL);
Value v = ASTInterpreter::execute(interpreter);
return v.o ? v.o : None;
}
Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
BoxedDict* locals) {
......
......@@ -32,6 +32,7 @@ extern const void* interpreter_instr_addr;
Box* astInterpretFunction(CompiledFunction* f, int nargs, Box* closure, Box* generator, Box* arg1, Box* arg2, Box* arg3,
Box** args);
Box* astInterpretFunctionEval(CompiledFunction* cf, BoxedDict* locals);
Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
BoxedDict* locals);
......
......@@ -302,7 +302,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
((void (*)())cf->code)();
}
static Box* compileAndRunExpression(AST_Expression* expr, BoxedModule* bm) {
static Box* compileAndRunExpression(AST_Expression* expr, BoxedModule* bm, BoxedDict* locals) {
CompiledFunction* cf;
{ // scope for limiting the locked region:
......@@ -317,16 +317,13 @@ static Box* compileAndRunExpression(AST_Expression* expr, BoxedModule* bm) {
SourceInfo* si = new SourceInfo(bm, scoping, expr, { stmt });
CLFunction* cl_f = new CLFunction(0, 0, false, false, si);
EffortLevel effort = initialEffort();
EffortLevel effort = EffortLevel::INTERPRETED;
cf = compileFunction(cl_f, new FunctionSpecialization(VOID), effort, NULL);
assert(cf->clfunc->versions.size());
}
if (cf->is_interpreted)
return astInterpretFunction(cf, 0, NULL, NULL, NULL, NULL, NULL, NULL);
else
return ((Box * (*)())cf->code)();
return astInterpretFunctionEval(cf, locals);
}
Box* runEval(const char* code, BoxedDict* locals, BoxedModule* module) {
......@@ -335,10 +332,10 @@ Box* runEval(const char* code, BoxedDict* locals, BoxedModule* module) {
// TODO this memory leaks
AST_Module* parsedModule = parse_string(code);
assert(parsedModule->body[0]->type == AST_TYPE::Expr);
AST_Expression* parsedExpr = new AST_Expression(std::unique_ptr<InternedStringPool>(new InternedStringPool()));
AST_Expression* parsedExpr = new AST_Expression(std::move(parsedModule->interned_strings));
parsedExpr->body = static_cast<AST_Expr*>(parsedModule->body[0])->value;
return compileAndRunExpression(parsedExpr, module);
return compileAndRunExpression(parsedExpr, module, locals);
}
// If a function version keeps failing its speculations, kill it (remove it
......
......@@ -2082,10 +2082,12 @@ private:
if (myblock->successors.size()) {
// TODO getTypeAtBlockEnd will automatically convert up to the concrete type, which we don't want
// here, but this is just for debugging so I guess let it happen for now:
/*
ConcreteCompilerType* ending_type = types->getTypeAtBlockEnd(it->first, myblock);
ASSERT(it->second->canConvertTo(ending_type), "%s is supposed to be %s, but somehow is %s",
it->first.c_str(), ending_type->debugName().c_str(),
it->second->getType()->debugName().c_str());
*/
}
#endif
......
......@@ -21,6 +21,9 @@ d = 19
e = 20
i = 21
def func():
loc = 231
print 'loc', eval("loc")
print eval("d")
e = 20
......@@ -101,6 +104,25 @@ print 'shadow1', shadow2
print 'shadow2', shadow2
print 'shadow3', shadow3
def func3():
loc = 1234
print eval("(lambda arg : arg + loc)(12)")
func3()
changing_global = -1
def print_changing_global():
print 'changing_global is', changing_global
return 0
eval("[print_changing_global() for changing_global in range(5)]")
def do_changing_local():
changing_local = -1
def print_changing_local():
print 'changing_local is', changing_local
return 0
eval("[print_changing_local() for changing_local in range(5)]")
do_changing_local()
x = 2
def wrap():
x = 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment