shove list comprehensions into their own fake call frames because everything is terrible
This commit is contained in:
parent
bb7e49add7
commit
0b2c9df58f
1
chunk.h
1
chunk.h
@ -73,6 +73,7 @@ typedef enum {
|
||||
OP_IMPORT_LONG,
|
||||
OP_GET_SUPER_LONG,
|
||||
OP_INC_LONG,
|
||||
OP_INLINE_FUNCTION,
|
||||
} KrkOpCode;
|
||||
|
||||
/**
|
||||
|
25
compiler.c
25
compiler.c
@ -119,6 +119,20 @@ static void initCompiler(Compiler * compiler, FunctionType type) {
|
||||
}
|
||||
}
|
||||
|
||||
static void initSubcompiler(Compiler * compiler) {
|
||||
compiler->enclosing = current;
|
||||
current = compiler;
|
||||
compiler->function = compiler->enclosing->function;
|
||||
compiler->type = compiler->enclosing->type;
|
||||
compiler->localCount = 0;
|
||||
compiler->scopeDepth = 1;
|
||||
compiler->localsSpace = 8;
|
||||
compiler->localsSpace = 8;
|
||||
compiler->locals = GROW_ARRAY(Local,NULL,0,8);
|
||||
compiler->upvaluesSpace = 0;
|
||||
compiler->upvalues = NULL;
|
||||
}
|
||||
|
||||
static void parsePrecedence(Precedence precedence);
|
||||
static ssize_t parseVariable(const char * errorMessage);
|
||||
static void variable(int canAssign);
|
||||
@ -262,6 +276,10 @@ static KrkFunction * endCompiler() {
|
||||
return function;
|
||||
}
|
||||
|
||||
static void endSubcompiler() {
|
||||
current = current->enclosing;
|
||||
}
|
||||
|
||||
static void freeCompiler(Compiler * compiler) {
|
||||
FREE_ARRAY(Local,compiler->locals, compiler->localsSpace);
|
||||
FREE_ARRAY(Upvalue,compiler->upvalues, compiler->upvaluesSpace);
|
||||
@ -1125,6 +1143,10 @@ static void super_(int canAssign) {
|
||||
}
|
||||
|
||||
static void list(int canAssign) {
|
||||
Compiler subcompiler;
|
||||
emitByte(OP_INLINE_FUNCTION);
|
||||
initSubcompiler(&subcompiler);
|
||||
|
||||
KrkToken listOf = syntheticToken("listOf");
|
||||
size_t ind = identifierConstant(&listOf);
|
||||
EMIT_CONSTANT_OP(OP_GET_GLOBAL, ind);
|
||||
@ -1273,6 +1295,9 @@ static void list(int canAssign) {
|
||||
advance();
|
||||
emitBytes(OP_CALL, 0);
|
||||
}
|
||||
emitByte(OP_RETURN);
|
||||
endSubcompiler();
|
||||
freeCompiler(&subcompiler);
|
||||
}
|
||||
|
||||
static void dict(int canAssign) {
|
||||
|
@ -2,3 +2,10 @@
|
||||
for i in [x * 5 for x in [1,7,3,5,9,2,8]]:
|
||||
print i
|
||||
|
||||
def sum(iterable):
|
||||
let total = 0
|
||||
for v in iterable:
|
||||
total = total + v
|
||||
return total
|
||||
|
||||
print sum([x * 3 for x in [y * 7 for y in [1,2,3,4,5]]])
|
||||
|
13
vm.c
13
vm.c
@ -420,6 +420,7 @@ static int call(KrkClosure * closure, int argCount) {
|
||||
return 0;
|
||||
}
|
||||
CallFrame * frame = &vm.frames[vm.frameCount++];
|
||||
frame->isInlined = 0;
|
||||
frame->closure = closure;
|
||||
frame->ip = closure->function->chunk.code;
|
||||
frame->slots = (vm.stackTop - argCount - 1) - vm.stack;
|
||||
@ -933,6 +934,9 @@ static KrkValue run() {
|
||||
KrkValue result = krk_pop();
|
||||
closeUpvalues(frame->slots);
|
||||
vm.frameCount--;
|
||||
if (frame->isInlined) {
|
||||
vm.frames[vm.frameCount - 1].ip = frame->ip;
|
||||
}
|
||||
if (vm.frameCount == 0) {
|
||||
krk_pop();
|
||||
return result;
|
||||
@ -1143,6 +1147,15 @@ static KrkValue run() {
|
||||
krk_tableAddAll(&vm.object_class->methods, &_class->methods);
|
||||
break;
|
||||
}
|
||||
case OP_INLINE_FUNCTION: {
|
||||
CallFrame * newFrame = &vm.frames[vm.frameCount++];
|
||||
newFrame->isInlined = 1;
|
||||
newFrame->closure = frame->closure;
|
||||
newFrame->ip = frame->ip;
|
||||
newFrame->slots = vm.stackTop - vm.stack;
|
||||
frame = newFrame;
|
||||
break;
|
||||
}
|
||||
case OP_GET_PROPERTY_LONG:
|
||||
case OP_GET_PROPERTY: {
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
|
Loading…
x
Reference in New Issue
Block a user