34 #include <sys/types.h> 
   46 #include "opcode_enum.h" 
  103     EXPR_CLASS_PARAMETERS,
 
  230 #define OPTIONS_FLAG_COMPILE_TIME_BUILTINS    (1 << 0) 
  231 #define OPTIONS_FLAG_NO_IMPLICIT_SELF         (1 << 1) 
  284 static void _GlobalState_gcscan(
KrkInstance * _self) {
 
  286     Compiler * compiler = 
self->current;
 
  287     while (compiler != NULL) {
 
  294 static void _GlobalState_gcsweep(
KrkInstance * _self) {
 
  298 #define currentChunk() (&state->current->codeobject->chunk) 
  300 #define EMIT_OPERAND_OP(opc, arg) do { if (arg < 256) { emitBytes(opc, arg); } \ 
  301     else { emitBytes(opc ## _LONG, arg >> 16); emitBytes(arg >> 8, arg); } } while (0) 
  303 static int isMethod(
int type) {
 
  307 static int isCoroutine(
int type) {
 
  311 static char * calculateQualName(
struct GlobalState * state) {
 
  312     static char space[1024]; 
 
  314     char * writer = &space[1023];
 
  316 #define WRITE(s) do { \ 
  317     size_t len = strlen(s); \ 
  318     if (writer - len < space) goto _exit; \ 
  320     memcpy(writer, s, len); \ 
  340 #define codeobject_from_chunk_pointer(ptr) ((KrkCodeObject*)((char *)(ptr) - offsetof(KrkCodeObject, chunk))) 
  342     return (
ChunkRecorder){in->count, in->linesCount, in->constants.
count, codeobject_from_chunk_pointer(in)->expressionsCount};
 
  346     out->count = from.
count;
 
  347     out->linesCount = from.
lines;
 
  349     codeobject_from_chunk_pointer(out)->expressionsCount = from.
expressions;
 
  351 #undef codeobject_from_chunk_pointer 
  359     compiler->
type = type;
 
  384         char * qualname = calculateQualName(state);
 
  388     if (isMethod(type) && !(compiler->
optionsFlags & OPTIONS_FLAG_NO_IMPLICIT_SELF)) {
 
  392         local->
name.start = 
"self";
 
  393         local->
name.length = 4;
 
  394         renameLocal(state, 0, local->
name);
 
  403         local->
name.start = 
"";
 
  404         local->
name.length = 0;
 
  405         renameLocal(state, 0, local->
name);
 
  413 static void rememberClassProperty(
struct GlobalState * state, 
size_t ind) {
 
  421 static ParseRule * getRule(KrkTokenType type);
 
  424 static void defDeclaration(
struct GlobalState * state);
 
  425 static void asyncDeclaration(
struct GlobalState * state, 
int);
 
  427 static void declaration(
struct GlobalState * state);
 
  429 static void declareVariable(
struct GlobalState * state);
 
  433 static void complexAssignmentTargets(
struct GlobalState * state, 
KrkScanner oldScanner, 
Parser oldParser, 
size_t targetCount, 
int parenthesized, 
size_t argBefore, 
size_t argAfter);
 
  434 static int invalidTarget(
struct GlobalState * state, 
int exprType, 
const char * description);
 
  438     if (!token->linePtr) token->linePtr = token->start;
 
  440     while (token->linePtr[i] && token->linePtr[i] != 
'\n') i++;
 
  459 #ifdef KRK_NO_DOCUMENTATION 
  460 # define raiseSyntaxError(token, ...) do { if (state->parser.hadError) break; krk_runtimeError(vm.exceptions->syntaxError, "syntax error"); finishError(state,token); } while (0)
 
  462 # define raiseSyntaxError(token, ...) do { if (state->parser.hadError) break; krk_runtimeError(vm.exceptions->syntaxError, __VA_ARGS__); finishError(state,token); } while (0) 
  465 #define error(...) raiseSyntaxError(&state->parser.previous, __VA_ARGS__) 
  466 #define errorAtCurrent(...) raiseSyntaxError(&state->parser.current, __VA_ARGS__) 
  485 #define advance() _advance(state) 
  487 static void _skipToEnd(
struct GlobalState * state) {
 
  491 #define skipToEnd() _skipToEnd(state) 
  493 static void _startEatingWhitespace(
struct GlobalState * state) {
 
  498 #define startEatingWhitespace() _startEatingWhitespace(state) 
  500 static void _stopEatingWhitespace(
struct GlobalState * state) {
 
  502         error(
"Internal scanner error: Invalid nesting of `startEatingWhitespace`/`stopEatingWhitespace` calls.");
 
  507 #define stopEatingWhitespace() _stopEatingWhitespace(state) 
  509 static void _consume(
struct GlobalState * state, KrkTokenType type, 
const char * message) {
 
  518     errorAtCurrent(
"%s", message);
 
  521 #define consume(...) _consume(state,__VA_ARGS__) 
  523 static int _check(
struct GlobalState * state, KrkTokenType type) {
 
  527 #define check(t) _check(state,t) 
  529 static int _match(
struct GlobalState * state, KrkTokenType type) {
 
  530     if (!check(type)) 
return 0;
 
  535 #define match(t) _match(state,t) 
  538     return (a->length == b->length && memcmp(a->start, b->start, a->length) == 0);
 
  544     token.length = (int)strlen(text);
 
  549 #define syntheticToken(t) _syntheticToken(state,t) 
  551 static void _emitByte(
struct GlobalState * state, uint8_t 
byte) {
 
  555 #define emitByte(b) _emitByte(state,b) 
  557 static void _emitBytes(
struct GlobalState * state, uint8_t byte1, uint8_t byte2) {
 
  562 #define emitBytes(a,b) _emitBytes(state,a,b) 
  564 static void emitReturn(
struct GlobalState * state) {
 
  574     for (
size_t i = 0; i < 
function->localNameCount; i++) {
 
  575         if (function->localNames[i].deathday == 0) {
 
  579     function->localNames = KRK_GROW_ARRAY(
KrkLocalEntry, function->localNames,
 
  587     function->chunk.lines = KRK_GROW_ARRAY(
KrkLineMap, function->chunk.lines,
 
  588         function->chunk.linesCapacity, function->chunk.linesCount);
 
  589     function->chunk.linesCapacity = 
function->chunk.linesCount;
 
  590     function->chunk.code = KRK_GROW_ARRAY(uint8_t, function->chunk.code,
 
  591         function->chunk.capacity, function->chunk.count);
 
  592     function->chunk.capacity = 
function->chunk.count;
 
  595         function->expressionsCapacity, function->expressionsCount);
 
  596     function->expressionsCapacity = 
function->expressionsCount;
 
  599     for (
int i = 0; i < 
function->potentialPositionals; ++i) {
 
  600         if (i < state->current->unnamedArgs) {
 
  610     size_t args = 
function->potentialPositionals;
 
  611     if (function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
 
  620     for (
int i = 0; i < 
function->keywordArgs; ++i) {
 
  627     args += 
function->keywordArgs;
 
  629     if (function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
 
  638     function->totalArguments = 
function->potentialPositionals + 
function->keywordArgs + !!(
function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) + !!(function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS);
 
  640 #if !defined(KRK_NO_DISASSEMBLY) && !defined(KRK_DISABLE_DEBUG) 
  650 static void freeCompiler(
Compiler * compiler) {
 
  667 #define emitConstant(v) _emitConstant(state,v) 
  669 static int isMangleable(
const char * name, 
size_t len) {
 
  670     return (len > 2 && name[0] == 
'_' && name[1] == 
'_' && name[len-1] != 
'_' && (len < 4 || name[len-2] != 
'_'));
 
  674     if (state->
currentClass && isMangleable(name->start, name->length)) {
 
  678         while (classLength && *className == 
'_') {
 
  684         krk_pushStringBuilderFormat(&sb,
"_%.*s%.*s",
 
  685             (
int)classLength, className,
 
  686             (
int)name->length, name->start);
 
  699     for (ssize_t i = compiler->
localCount - 1; i >= 0; i--) {
 
  701         if (identifiersEqual(name, &local->
name)) {
 
  702             if (local->
depth == -1) {
 
  703                 error(
"Invalid recursive reference in declaration initializer");
 
  705             if (local->
depth == -2) {
 
  740         renameLocal(state, out, name);
 
  746 static void declareVariable(
struct GlobalState * state) {
 
  753         if (identifiersEqual(name, &local->
name)) {
 
  754             error(
"Duplicate definition for local '%.*s' in this scope.", (
int)name->literalWidth, name->start);
 
  757     addLocal(state, *name);
 
  760 static ssize_t parseVariable(
struct GlobalState * state, 
const char * errorMessage) {
 
  761     consume(TOKEN_IDENTIFIER, errorMessage);
 
  763     declareVariable(state);
 
  769             error(
"Conflicting declaration of global '%.*s' is invalid when 'compile_time_builtins' is enabled.",
 
  778 static void markInitialized(
struct GlobalState * state) {
 
  783 static size_t anonymousLocal(
struct GlobalState * state) {
 
  784     size_t val = addLocal(state, syntheticToken(
""));
 
  785     markInitialized(state);
 
  789 static void defineVariable(
struct GlobalState * state, 
size_t global) {
 
  791         markInitialized(state);
 
  795     EMIT_OPERAND_OP(OP_DEFINE_GLOBAL, global);
 
  800     invalidTarget(state, exprType, 
"literal");
 
  803         if (start[j] == 
'x' || start[j] == 
'X') 
break;
 
  804         if (start[j] == 
'.' || start[j] == 
'e' || start[j] == 
'E') {
 
  808             error(
"no float support");
 
  816     if (IS_NONE(result)) {
 
  817         error(
"invalid numeric literal");
 
  820     emitConstant(result);
 
  823 static int _emitJump(
struct GlobalState * state, uint8_t opcode) {
 
  825     emitBytes(0xFF, 0xFF);
 
  826     return currentChunk()->count - 2;
 
  828 #define emitJump(o) _emitJump(state,o) 
  841 static void _emitOverlongJump(
struct GlobalState * state, 
int offset, 
int jump) {
 
  855         currentChunk()->code[offset-1] = OP_OVERLONG_JUMP;
 
  861 static void _patchJump(
struct GlobalState * state, 
int offset) {
 
  862     int jump = currentChunk()->count - offset - 2;
 
  865         _emitOverlongJump(state, offset, jump);
 
  868     currentChunk()->code[offset] = (jump >> 8) & 0xFF;
 
  869     currentChunk()->code[offset + 1] =  (jump) & 0xFF;
 
  872 #define patchJump(o) _patchJump(state,o) 
  892 #ifndef KRK_DISABLE_DEBUG 
  894     if (after->linePtr != before->linePtr) 
return;
 
  900     if (before->col > 255 || current->col > 255 ||
 
  901         (current->col + current->literalWidth) > 255 ||
 
  902         (after->col + after->literalWidth) > 255) 
return;
 
  905         before->col, current->col,
 
  906         current->col + current->literalWidth,
 
  907         after->col + after->literalWidth);
 
  913     if (operatorType == TOKEN_NOT) consume(TOKEN_IN, 
"'in' must follow infix 'not'");
 
  914     int invert = (operatorType == TOKEN_IS && match(TOKEN_NOT));
 
  918     ParseRule * rule = getRule(operatorType);
 
  923         emitBytes(OP_DUP, 1);
 
  926     switch (operatorType) {
 
  927         case TOKEN_BANG_EQUAL:    emitByte(OP_EQUAL); invert = 1; 
break;
 
  928         case TOKEN_EQUAL_EQUAL:   emitByte(OP_EQUAL); 
break;
 
  929         case TOKEN_GREATER:       emitByte(OP_GREATER); 
break;
 
  930         case TOKEN_GREATER_EQUAL: emitByte(OP_GREATER_EQUAL); 
break;
 
  931         case TOKEN_LESS:          emitByte(OP_LESS); 
break;
 
  932         case TOKEN_LESS_EQUAL:    emitByte(OP_LESS_EQUAL); 
break;
 
  934         case TOKEN_IS: emitByte(OP_IS); 
break;
 
  936         case TOKEN_IN: emitByte(OP_INVOKE_CONTAINS); 
break;
 
  937         case TOKEN_NOT: emitByte(OP_INVOKE_CONTAINS); invert = 1; 
break;
 
  939         default: error(
"Invalid binary comparison operator?"); 
break;
 
  942     writeExpressionLocation(preceding, &state->
parser.
previous, &
this, state);
 
  943     if (invert) emitByte(OP_NOT);
 
  946         size_t exitJump = emitJump(OP_JUMP_IF_FALSE_OR_POP);
 
  948         compareChained(state, 1, &next);
 
  952                 emitBytes(OP_SWAP,OP_POP);
 
  963     invalidTarget(state, exprType, 
"operator");
 
  968     ParseRule * rule = getRule(operatorType);
 
  971     invalidTarget(state, exprType, 
"operator");
 
  973     switch (operatorType) {
 
  974         case TOKEN_PIPE:        emitByte(OP_BITOR); 
break;
 
  975         case TOKEN_CARET:       emitByte(OP_BITXOR); 
break;
 
  976         case TOKEN_AMPERSAND:   emitByte(OP_BITAND); 
break;
 
  977         case TOKEN_LEFT_SHIFT:  emitByte(OP_SHIFTLEFT); 
break;
 
  978         case TOKEN_RIGHT_SHIFT: emitByte(OP_SHIFTRIGHT); 
break;
 
  980         case TOKEN_PLUS:     emitByte(OP_ADD); 
break;
 
  981         case TOKEN_MINUS:    emitByte(OP_SUBTRACT); 
break;
 
  982         case TOKEN_ASTERISK: emitByte(OP_MULTIPLY); 
break;
 
  983         case TOKEN_POW:      emitByte(OP_POW); 
break;
 
  984         case TOKEN_SOLIDUS:  emitByte(OP_DIVIDE); 
break;
 
  985         case TOKEN_DOUBLE_SOLIDUS: emitByte(OP_FLOORDIV); 
break;
 
  986         case TOKEN_MODULO:   emitByte(OP_MODULO); 
break;
 
  987         case TOKEN_IN:       emitByte(OP_EQUAL); 
break;
 
  988         case TOKEN_AT:       emitByte(OP_MATMUL); 
break;
 
  994 static int matchAssignment(
struct GlobalState * state) {
 
  998 static int checkEndOfDel(
struct GlobalState * state) {
 
  999     if (check(TOKEN_COMMA) || check(TOKEN_EOL) || check(TOKEN_EOF) || check(TOKEN_SEMICOLON)) {
 
 1006 static int matchComplexEnd(
struct GlobalState * state) {
 
 1007     return match(TOKEN_COMMA) ||
 
 1008             match(TOKEN_EQUAL) ||
 
 1009             match(TOKEN_RIGHT_PAREN);
 
 1012 static int invalidTarget(
struct GlobalState * state, 
int exprType, 
const char * description) {
 
 1014         error(
"Can not assign to %s", description);
 
 1019         error(
"Can not delete %s", description);
 
 1026 static void assignmentValue(
struct GlobalState * state) {
 
 1029     if (type == TOKEN_PLUS_PLUS || type == TOKEN_MINUS_MINUS) {
 
 1030         emitConstant(INTEGER_VAL(1));
 
 1036         case TOKEN_PIPE_EQUAL:      emitByte(OP_INPLACE_BITOR); 
break;
 
 1037         case TOKEN_CARET_EQUAL:     emitByte(OP_INPLACE_BITXOR); 
break;
 
 1038         case TOKEN_AMP_EQUAL:       emitByte(OP_INPLACE_BITAND); 
break;
 
 1039         case TOKEN_LSHIFT_EQUAL:    emitByte(OP_INPLACE_SHIFTLEFT); 
break;
 
 1040         case TOKEN_RSHIFT_EQUAL:    emitByte(OP_INPLACE_SHIFTRIGHT); 
break;
 
 1042         case TOKEN_PLUS_EQUAL:      emitByte(OP_INPLACE_ADD); 
break;
 
 1043         case TOKEN_PLUS_PLUS:       emitByte(OP_INPLACE_ADD); 
break;
 
 1044         case TOKEN_MINUS_EQUAL:     emitByte(OP_INPLACE_SUBTRACT); 
break;
 
 1045         case TOKEN_MINUS_MINUS:     emitByte(OP_INPLACE_SUBTRACT); 
break;
 
 1046         case TOKEN_ASTERISK_EQUAL:  emitByte(OP_INPLACE_MULTIPLY); 
break;
 
 1047         case TOKEN_POW_EQUAL:       emitByte(OP_INPLACE_POW); 
break;
 
 1048         case TOKEN_SOLIDUS_EQUAL:   emitByte(OP_INPLACE_DIVIDE); 
break;
 
 1049         case TOKEN_DSOLIDUS_EQUAL:  emitByte(OP_INPLACE_FLOORDIV); 
break;
 
 1050         case TOKEN_MODULO_EQUAL:    emitByte(OP_INPLACE_MODULO); 
break;
 
 1051         case TOKEN_AT_EQUAL:        emitByte(OP_INPLACE_MATMUL); 
break;
 
 1054             error(
"Unexpected operand in assignment");
 
 1057     writeExpressionLocation(&left,&state->
parser.
previous,&left,state);
 
 1060 static void expression(
struct GlobalState * state) {
 
 1064 static void sliceExpression(
struct GlobalState * state) {
 
 1066     if (match(TOKEN_COLON)) {
 
 1072     if (isSlice || match(TOKEN_COLON)) {
 
 1074         if (check(TOKEN_RIGHT_SQUARE) || check(TOKEN_COMMA)) {
 
 1077             EMIT_OPERAND_OP(OP_SLICE, 2);
 
 1079             if (check(TOKEN_COLON)) {
 
 1086             if (match(TOKEN_COLON) && !check(TOKEN_RIGHT_SQUARE) && !check(TOKEN_COMMA)) {
 
 1089                 EMIT_OPERAND_OP(OP_SLICE, 3);
 
 1092                 EMIT_OPERAND_OP(OP_SLICE, 2);
 
 1103     sliceExpression(state);
 
 1105     if (match(TOKEN_COMMA)) {
 
 1106         size_t argCount = 1;
 
 1107         if (!check(TOKEN_RIGHT_SQUARE)) {
 
 1109                 sliceExpression(state);
 
 1111             } 
while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_SQUARE));
 
 1113         EMIT_OPERAND_OP(OP_TUPLE, argCount);
 
 1116     consume(TOKEN_RIGHT_SQUARE, 
"Expected ']' after index.");
 
 1118         if (matchComplexEnd(state)) {
 
 1119             EMIT_OPERAND_OP(OP_DUP, 2);
 
 1120             emitByte(OP_INVOKE_SETTER);
 
 1121             writeExpressionLocation(left,&state->
parser.
current,&
this,state);
 
 1129         emitByte(OP_INVOKE_SETTER);
 
 1130         writeExpressionLocation(left,&state->
parser.
previous,&
this,state);
 
 1132         emitBytes(OP_DUP, 1); 
 
 1133         emitBytes(OP_DUP, 1); 
 
 1134         emitByte(OP_INVOKE_GETTER); 
 
 1135         writeExpressionLocation(left,&state->
parser.
previous,&
this,state);
 
 1136         assignmentValue(state); 
 
 1137         emitByte(OP_INVOKE_SETTER); 
 
 1138         writeExpressionLocation(left,&state->
parser.
previous,&
this,state);
 
 1140         emitByte(OP_INVOKE_DELETE);
 
 1141         writeExpressionLocation(left,&state->
parser.
previous,&
this,state);
 
 1143         emitByte(OP_INVOKE_GETTER);
 
 1144         writeExpressionLocation(left,&state->
parser.
previous,&
this,state);
 
 1148 static void attributeUnpack(
struct GlobalState * state, 
int exprType) {
 
 1149     startEatingWhitespace();
 
 1150     size_t argCount = 0;
 
 1151     size_t argSpace = 1;
 
 1152     ssize_t * args  = KRK_GROW_ARRAY(ssize_t,NULL,0,1);
 
 1155         if (argSpace < argCount + 1) {
 
 1156             size_t old = argSpace;
 
 1157             argSpace = KRK_GROW_CAPACITY(old);
 
 1158             args = KRK_GROW_ARRAY(ssize_t,args,old,argSpace);
 
 1160         consume(TOKEN_IDENTIFIER, 
"Expected attribute name");
 
 1162         args[argCount++] = ind;
 
 1163     } 
while (match(TOKEN_COMMA));
 
 1165     stopEatingWhitespace();
 
 1166     consume(TOKEN_RIGHT_PAREN, 
"Expected ')' after attribute list");
 
 1169         error(
"Can not assign to '.(' in multiple target list");
 
 1174         size_t expressionCount = 0;
 
 1178         } 
while (match(TOKEN_COMMA));
 
 1180         if (expressionCount == 1 && argCount > 1) {
 
 1181             EMIT_OPERAND_OP(OP_UNPACK, argCount);
 
 1182         } 
else if (expressionCount > 1 && argCount == 1) {
 
 1183             EMIT_OPERAND_OP(OP_TUPLE, expressionCount);
 
 1184         } 
else if (expressionCount != argCount) {
 
 1185             error(
"Invalid assignment to attribute pack");
 
 1189         for (
size_t i = argCount; i > 0; i--) {
 
 1191                 emitBytes(OP_DUP, i);
 
 1194             EMIT_OPERAND_OP(OP_SET_PROPERTY, args[i-1]);
 
 1200         for (
size_t i = 0; i < argCount; i++) {
 
 1201             emitBytes(OP_DUP,0);
 
 1202             EMIT_OPERAND_OP(OP_GET_PROPERTY,args[i]);
 
 1206         emitBytes(OP_TUPLE,argCount);
 
 1210     KRK_FREE_ARRAY(ssize_t,args,argSpace);
 
 1215     if (match(TOKEN_LEFT_PAREN)) {
 
 1216         attributeUnpack(state, exprType);
 
 1221     consume(TOKEN_IDENTIFIER, 
"Expected property name");
 
 1224         if (matchComplexEnd(state)) {
 
 1225             EMIT_OPERAND_OP(OP_DUP, 1);
 
 1226             EMIT_OPERAND_OP(OP_SET_PROPERTY, ind);
 
 1235         EMIT_OPERAND_OP(OP_SET_PROPERTY, ind);
 
 1238         emitBytes(OP_DUP, 0); 
 
 1239         EMIT_OPERAND_OP(OP_GET_PROPERTY, ind);
 
 1241         assignmentValue(state);
 
 1242         EMIT_OPERAND_OP(OP_SET_PROPERTY, ind);
 
 1245         EMIT_OPERAND_OP(OP_DEL_PROPERTY, ind);
 
 1247     } 
else if (match(TOKEN_LEFT_PAREN)) {
 
 1248         EMIT_OPERAND_OP(OP_GET_METHOD, ind);
 
 1252         EMIT_OPERAND_OP(OP_GET_PROPERTY, ind);
 
 1258     invalidTarget(state, exprType, 
"literal");
 
 1260         case TOKEN_FALSE: emitByte(OP_FALSE); 
break;
 
 1261         case TOKEN_NONE:  emitByte(OP_NONE); 
break;
 
 1262         case TOKEN_TRUE:  emitByte(OP_TRUE); 
break;
 
 1268     invalidTarget(state, exprType, 
"literal");
 
 1271         error(
"internal compiler error");
 
 1274     emitConstant(value);
 
 1277 static void typeHintLocal(
struct GlobalState * state) {
 
 1287 static void letDeclaration(
struct GlobalState * state) {
 
 1288     size_t argCount = 0;
 
 1289     size_t argSpace = 1;
 
 1290     ssize_t * args  = KRK_GROW_ARRAY(ssize_t,NULL,0,1);
 
 1293         if (argSpace < argCount + 1) {
 
 1294             size_t old = argSpace;
 
 1295             argSpace = KRK_GROW_CAPACITY(old);
 
 1296             args = KRK_GROW_ARRAY(ssize_t,args,old,argSpace);
 
 1298         ssize_t ind = parseVariable(state, 
"Expected variable name.");
 
 1304             args[argCount++] = ind;
 
 1306         if (check(TOKEN_COLON)) {
 
 1310                 typeHintLocal(state);
 
 1312                 KrkToken annotations = syntheticToken(
"__annotations__");
 
 1313                 size_t ind = identifierConstant(state, &annotations);
 
 1314                 EMIT_OPERAND_OP(OP_GET_GLOBAL, ind);
 
 1315                 emitConstant(OBJECT_VAL(
krk_copyString(name.start, name.length)));
 
 1317                 emitBytes(OP_INVOKE_SETTER, OP_POP);
 
 1320     } 
while (match(TOKEN_COMMA));
 
 1322     if (match(TOKEN_EQUAL)) {
 
 1323         size_t expressionCount = 0;
 
 1327         } 
while (match(TOKEN_COMMA));
 
 1328         if (expressionCount == 1 && argCount > 1) {
 
 1329             EMIT_OPERAND_OP(OP_UNPACK, argCount);
 
 1330         } 
else if (expressionCount == argCount) {
 
 1332         } 
else if (expressionCount > 1 && argCount == 1) {
 
 1333             EMIT_OPERAND_OP(OP_TUPLE, expressionCount);
 
 1335             error(
"Invalid sequence unpack in 'let' statement");
 
 1340         for (
size_t i = 0; i < argCount; ++i) {
 
 1346         for (
size_t i = argCount; i > 0; i--) {
 
 1347             defineVariable(state, args[i-1]);
 
 1350         for (
size_t i = 0; i < argCount; i++) {
 
 1356     KRK_FREE_ARRAY(ssize_t,args,argSpace);
 
 1360 static void declaration(
struct GlobalState * state) {
 
 1361     if (check(TOKEN_DEF)) {
 
 1362         defDeclaration(state);
 
 1363     } 
else if (check(TOKEN_CLASS)) {
 
 1364         KrkToken className = classDeclaration(state);
 
 1365         size_t classConst = identifierConstant(state, &className);
 
 1367         declareVariable(state);
 
 1368         defineVariable(state, classConst);
 
 1369     } 
else if (check(TOKEN_AT)) {
 
 1371     } 
else if (check(TOKEN_ASYNC)) {
 
 1372         asyncDeclaration(state, 1);
 
 1373     } 
else if (match(TOKEN_EOL) || match(TOKEN_EOF)) {
 
 1375     } 
else if (check(TOKEN_INDENTATION)) {
 
 1384 static void expressionStatement(
struct GlobalState * state) {
 
 1389 static void beginScope(
struct GlobalState * state) {
 
 1393 static void endScope(
struct GlobalState * state) {
 
 1403                 if (popCount == 1) emitByte(OP_POP);
 
 1404                 else { EMIT_OPERAND_OP(OP_POP_MANY, popCount); }
 
 1410                 if (closeCount == 1) emitByte(OP_CLOSE_UPVALUE);
 
 1411                 else { EMIT_OPERAND_OP(OP_CLOSE_MANY, closeCount); }
 
 1427         if (popCount == 1) emitByte(OP_POP);
 
 1428         else { EMIT_OPERAND_OP(OP_POP_MANY, popCount); }
 
 1431         if (closeCount == 1) emitByte(OP_CLOSE_UPVALUE);
 
 1432         else { EMIT_OPERAND_OP(OP_CLOSE_MANY, closeCount); }
 
 1436 static void block(
struct GlobalState * state, 
size_t indentation, 
const char * blockName) {
 
 1437     if (match(TOKEN_EOL)) {
 
 1438         if (check(TOKEN_INDENTATION)) {
 
 1440             if (currentIndentation <= indentation) 
return;
 
 1442             if (!strcmp(blockName,
"def") && (match(TOKEN_STRING) || match(TOKEN_BIG_STRING))) {
 
 1443                 size_t before = currentChunk()->count;
 
 1449                 currentChunk()->count = before;
 
 1452                 consume(TOKEN_EOL,
"Garbage after docstring defintion");
 
 1453                 if (!check(TOKEN_INDENTATION) || state->
parser.
current.length != currentIndentation) {
 
 1454                     error(
"Expected at least one statement in function with docstring.");
 
 1459             while (check(TOKEN_INDENTATION)) {
 
 1460                 if (state->
parser.
current.length < currentIndentation) 
break;
 
 1463                 if (check(TOKEN_EOL)) {
 
 1475     assert(!!function->upvalueCount == !!compiler->
upvalues);
 
 1476     for (
size_t i = 0; i < 
function->upvalueCount; ++i) {
 
 1480             emitByte((index >> 16) & 0xFF);
 
 1481             emitByte((index >> 8) & 0xFF);
 
 1483         emitByte(index & 0xFF);
 
 1494     emitConstant(OBJECT_VAL(
krk_copyString(name.start, name.length)));
 
 1501 static void hideLocal(
struct GlobalState * state) {
 
 1505 static void argumentDefinition(
struct GlobalState * state, 
int hasCollectors) {
 
 1506     if (match(TOKEN_EQUAL)) {
 
 1517         EMIT_OPERAND_OP(OP_GET_LOCAL, myLocal);
 
 1518         int jumpIndex = emitJump(OP_TEST_ARG);
 
 1521         EMIT_OPERAND_OP(OP_SET_LOCAL_POP, myLocal);
 
 1523         patchJump(jumpIndex);
 
 1524         if (hasCollectors) {
 
 1530         if (hasCollectors) {
 
 1532             EMIT_OPERAND_OP(OP_GET_LOCAL, myLocal);
 
 1533             int jumpIndex = emitJump(OP_TEST_ARG);
 
 1535             patchJump(jumpIndex);
 
 1539                 error(
"non-default argument follows default argument");
 
 1554     EMIT_OPERAND_OP(OP_CLOSURE, ind);
 
 1555     doUpvalues(state, compiler, func);
 
 1557         emitByte(OP_ANNOTATE);
 
 1559     freeCompiler(compiler);
 
 1563     int hasCollectors = 0;
 
 1564     KrkToken self = syntheticToken(
"self");
 
 1568                 isMethod(type) && check(TOKEN_IDENTIFIER) &&
 
 1571                 errorAtCurrent(
"Argument name 'self' in a method signature is reserved for the implicit first argument.");
 
 1578                 typeHint(state, name);
 
 1580             if (check(TOKEN_EQUAL)) {
 
 1581                 errorAtCurrent(
"'self' can not be a default argument.");
 
 1586         if (match(TOKEN_SOLIDUS)) {
 
 1588                 error(
"Syntax error.");
 
 1594         if (match(TOKEN_ASTERISK) || check(TOKEN_POW)) {
 
 1595             if (match(TOKEN_POW)) {
 
 1596                 if (hasCollectors == 2) {
 
 1597                     error(
"Duplicate ** in parameter list.");
 
 1603                 if (hasCollectors) {
 
 1604                     error(
"Syntax error.");
 
 1608                 if (check(TOKEN_COMMA)) {
 
 1614             ssize_t paramConstant = parseVariable(state,
 
 1615                 (hasCollectors == 1) ? 
"Expected parameter name after '*'." : 
"Expected parameter name after '**'.");
 
 1617             defineVariable(state, paramConstant);
 
 1619             if (!(state->
current->
optionsFlags & OPTIONS_FLAG_NO_IMPLICIT_SELF) && isMethod(type) && identifiersEqual(&name,&
self)) {
 
 1620                 errorAtCurrent(
"Argument name 'self' in a method signature is reserved for the implicit first argument.");
 
 1625                 typeHint(state, name);
 
 1629             EMIT_OPERAND_OP(OP_GET_LOCAL, myLocal);
 
 1631             int jumpIndex = emitJump(OP_TEST_ARG);
 
 1634             if (hasCollectors == 1) EMIT_OPERAND_OP(OP_MAKE_LIST,0);
 
 1635             else EMIT_OPERAND_OP(OP_MAKE_DICT,0);
 
 1636             EMIT_OPERAND_OP(OP_SET_LOCAL_POP, myLocal);
 
 1639             patchJump(jumpIndex);
 
 1642         if (hasCollectors == 2) {
 
 1643             error(
"arguments follow catch-all keyword collector");
 
 1646         ssize_t paramConstant = parseVariable(state, 
"Expected parameter name.");
 
 1652             typeHint(state, name);
 
 1654         argumentDefinition(state, hasCollectors);
 
 1655         defineVariable(state, paramConstant);
 
 1656     } 
while (match(TOKEN_COMMA));
 
 1663     initCompiler(state, &compiler, type);
 
 1668     consume(TOKEN_LEFT_PAREN, 
"Expected start of parameter list after function name.");
 
 1669     startEatingWhitespace();
 
 1670     if (!check(TOKEN_RIGHT_PAREN)) {
 
 1671         if (argumentList(state, type)) 
goto _bail;
 
 1673     stopEatingWhitespace();
 
 1674     consume(TOKEN_RIGHT_PAREN, 
"Expected end of parameter list.");
 
 1676     if (match(TOKEN_ARROW)) {
 
 1677         typeHint(state, syntheticToken(
"return"));
 
 1680     consume(TOKEN_COLON, 
"Expected colon after function signature.");
 
 1681     block(state, blockWidth,
"def");
 
 1683     functionPrologue(state, &compiler);
 
 1686 static void classBody(
struct GlobalState * state, 
size_t blockWidth) {
 
 1687     if (match(TOKEN_EOL)) {
 
 1691     if (check(TOKEN_AT)) {
 
 1694     } 
else if (match(TOKEN_IDENTIFIER)) {
 
 1698         if (check(TOKEN_COLON)) {
 
 1703             KrkToken annotations = syntheticToken(
"__annotations__");
 
 1704             size_t ind = identifierConstant(state, &annotations);
 
 1706                 EMIT_OPERAND_OP(OP_MAKE_DICT, 0);
 
 1707                 EMIT_OPERAND_OP(OP_SET_NAME, ind);
 
 1710                 EMIT_OPERAND_OP(OP_GET_NAME, ind);
 
 1712             emitConstant(OBJECT_VAL(
krk_copyString(name.start, name.length)));
 
 1714             emitBytes(OP_INVOKE_SETTER, OP_POP);
 
 1717             if (match(TOKEN_EOL) || match(TOKEN_EOF)) 
return;
 
 1720         consume(TOKEN_EQUAL, 
"Class field must have value.");
 
 1725         rememberClassProperty(state, ind);
 
 1726         EMIT_OPERAND_OP(OP_SET_NAME, ind);
 
 1729         if (!match(TOKEN_EOL) && !match(TOKEN_EOF)) {
 
 1730             errorAtCurrent(
"Expected end of line after class attribute declaration");
 
 1732     } 
else if (match(TOKEN_PASS)) {
 
 1734         consume(TOKEN_EOL, 
"Expected end of line after 'pass' in class body.");
 
 1738         if (match(TOKEN_ASYNC)) {
 
 1740             consume(TOKEN_DEF, 
"Expected 'def' after 'async'");
 
 1741         } 
else if (!match(TOKEN_DEF)) {
 
 1742             error(
"Expected method, decorator, or class variable.");
 
 1744         consume(TOKEN_IDENTIFIER, 
"Expected method name after 'def'");
 
 1747         static struct CompilerSpecialMethod { 
const char * name; 
int type; } compilerSpecialMethods[] = {
 
 1755         for (
struct CompilerSpecialMethod * method = compilerSpecialMethods; method->name; method++) {
 
 1756             if (state->
parser.
previous.length == strlen(method->name) && memcmp(state->
parser.
previous.start, method->name, strlen(method->name)) == 0) {
 
 1758                     error(
"'%s' can not be a coroutine",method->name);
 
 1761                 type = method->type;
 
 1765         function(state, type, blockWidth);
 
 1766         rememberClassProperty(state, ind);
 
 1767         EMIT_OPERAND_OP(OP_SET_NAME, ind);
 
 1772 #define ATTACH_PROPERTY(propName,how,propValue) do { \ 
 1773     KrkToken val_tok = syntheticToken(propValue); \ 
 1774     size_t val_ind = nonidentifierTokenConstant(state, &val_tok); \ 
 1775     EMIT_OPERAND_OP(how, val_ind); \ 
 1776     KrkToken name_tok = syntheticToken(propName); \ 
 1777     size_t name_ind = identifierConstant(state, &name_tok); \ 
 1778     EMIT_OPERAND_OP(OP_SET_NAME, name_ind); \ 
 1787     consume(TOKEN_IDENTIFIER, 
"Expected class name after 'class'.");
 
 1789     emitByte(OP_PUSH_BUILD_CLASS);
 
 1792     initCompiler(state, &subcompiler, 
TYPE_CLASS);
 
 1798     assert(addUpvalue(state, state->
current, 0, 4, classNameToken) == 0);
 
 1809     if (match(TOKEN_LEFT_PAREN)) {
 
 1811         while (!check(TOKEN_EOF)) {
 
 1812             if (check(TOKEN_RIGHT_PAREN) && parenDepth == 0) {
 
 1815             } 
else if (match(TOKEN_LEFT_BRACE)) {
 
 1817             } 
else if (match(TOKEN_RIGHT_BRACE)) {
 
 1827     consume(TOKEN_COLON, 
"Expected ':' after class.");
 
 1831     ATTACH_PROPERTY(
"__module__", OP_GET_GLOBAL, 
"__name__");
 
 1832     ATTACH_PROPERTY(
"__qualname__", OP_CONSTANT, calculateQualName(state));
 
 1834     if (match(TOKEN_EOL)) {
 
 1835         if (check(TOKEN_INDENTATION)) {
 
 1837             if (currentIndentation <= blockWidth) {
 
 1838                 errorAtCurrent(
"Unexpected indentation level for class");
 
 1841             if (match(TOKEN_STRING) || match(TOKEN_BIG_STRING)) {
 
 1843                 KrkToken doc = syntheticToken(
"__doc__");
 
 1844                 size_t ind = identifierConstant(state, &doc);
 
 1845                 EMIT_OPERAND_OP(OP_SET_NAME, ind);
 
 1847                 consume(TOKEN_EOL,
"Garbage after docstring defintion");
 
 1848                 if (!check(TOKEN_INDENTATION) || state->
parser.
current.length != currentIndentation) {
 
 1853             classBody(state, currentIndentation);
 
 1854             while (check(TOKEN_INDENTATION)) {
 
 1855                 if (state->
parser.
current.length < currentIndentation) 
break;
 
 1857                 classBody(state, currentIndentation);
 
 1865     size_t indFunc = 
krk_addConstant(currentChunk(), OBJECT_VAL(makeclass));
 
 1869     size_t nameInd = nonidentifierTokenConstant(state, &classNameToken);
 
 1874     EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
 
 1875     doUpvalues(state, &subcompiler, makeclass);
 
 1876     freeCompiler(&subcompiler);
 
 1877     EMIT_OPERAND_OP(OP_CONSTANT, nameInd);
 
 1879     if (match(TOKEN_LEFT_PAREN)) {
 
 1880         call(state, EXPR_CLASS_PARAMETERS, NULL);
 
 1882         emitBytes(OP_CALL, 2);
 
 1888     return classCompiler.
name;
 
 1894     initCompiler(state, &lambdaCompiler, 
TYPE_LAMBDA);
 
 1898     if (!check(TOKEN_COLON)) {
 
 1902     consume(TOKEN_COLON, 
"Expected ':' after lambda arguments");
 
 1906     functionPrologue(state, &lambdaCompiler);
 
 1908     invalidTarget(state, exprType, 
"lambda");
 
 1911 static void defDeclaration(
struct GlobalState * state) {
 
 1915     ssize_t global = parseVariable(state, 
"Expected function name after 'def'.");
 
 1917     markInitialized(state);
 
 1920     defineVariable(state, global);
 
 1923 static void asyncDeclaration(
struct GlobalState * state, 
int declarationLevel) {
 
 1927     if (match(TOKEN_DEF)) {
 
 1928         if (!declarationLevel) {
 
 1929             error(
"'async def' not valid here");
 
 1932         ssize_t global = parseVariable(state, 
"Expected coroutine name after 'async def'");
 
 1934         markInitialized(state);
 
 1937         defineVariable(state, global);
 
 1938     } 
else if (match(TOKEN_FOR)) {
 
 1940             error(
"'async for' outside of async function");
 
 1943         error(
"'async for' unsupported (GH-12)");
 
 1945     } 
else if (match(TOKEN_WITH)) {
 
 1947             error(
"'async with' outside of async function");
 
 1950         error(
"'async with' unsupported (GH-12)");
 
 1953         errorAtCurrent(
"Expected 'def' after 'async'.");
 
 1965     KrkToken at_staticmethod = syntheticToken(
"staticmethod");
 
 1966     KrkToken at_classmethod  = syntheticToken(
"classmethod");
 
 1979     consume(TOKEN_EOL, 
"Expected end of line after decorator.");
 
 1981         consume(TOKEN_INDENTATION, 
"Expected next line after decorator to have same indentation.");
 
 1982         if (state->
parser.
previous.length != blockWidth) error(
"Expected next line after decorator to have same indentation.");
 
 1985     if (check(TOKEN_DEF)) {
 
 1988         consume(TOKEN_IDENTIFIER, 
"Expected function name after 'def'");
 
 1990         if (type == 
TYPE_METHOD && funcName.length == 8 && !memcmp(funcName.start,
"__init__",8)) {
 
 1994             declareVariable(state);
 
 1995             markInitialized(state);
 
 1997         function(state, type, blockWidth);
 
 1998     } 
else if (match(TOKEN_ASYNC)) {
 
 1999         if (!match(TOKEN_DEF)) {
 
 2000             errorAtCurrent(
"Expected 'def' after 'async' with decorator, not '%*.s'",
 
 2003         consume(TOKEN_IDENTIFIER, 
"Expected coroutine name after 'def'.");
 
 2006             declareVariable(state);
 
 2007             markInitialized(state);
 
 2010     } 
else if (check(TOKEN_AT)) {
 
 2011         funcName = decorator(state, level+1, type);
 
 2012     } 
else if (check(TOKEN_CLASS)) {
 
 2014             error(
"Invalid decorator applied to class");
 
 2017         funcName = classDeclaration(state);
 
 2019         error(
"Expected a function declaration or another decorator.");
 
 2023     emitBytes(OP_CALL, 1);
 
 2028                 size_t ind = identifierConstant(state, &funcName);
 
 2029                 defineVariable(state, ind);
 
 2031                 emitByte(OP_SWAP_POP);
 
 2034             size_t ind = identifierConstant(state, &funcName);
 
 2035             rememberClassProperty(state, ind);
 
 2036             EMIT_OPERAND_OP(OP_SET_NAME, ind);
 
 2044 static void emitLoop(
struct GlobalState * state, 
int loopStart, uint8_t loopType) {
 
 2054     int offset = currentChunk()->count - loopStart + ((loopType == OP_LOOP_ITER) ? -1 : 2);
 
 2055     if (offset > 0xFFFF) {
 
 2056         _emitOverlongJump(state, currentChunk()->count, offset);
 
 2058     emitBytes(offset >> 8, offset);
 
 2063 static void withStatement(
struct GlobalState * state) {
 
 2074     if (match(TOKEN_AS)) {
 
 2075         consume(TOKEN_IDENTIFIER, 
"Expected variable name after 'as'");
 
 2077         declareVariable(state);
 
 2078         defineVariable(state, ind);
 
 2081         anonymousLocal(state);
 
 2085     anonymousLocal(state);
 
 2088     anonymousLocal(state);
 
 2089     int withJump = emitJump(OP_PUSH_WITH);
 
 2091     if (check(TOKEN_COMMA)) {
 
 2093         withStatement(state); 
 
 2095         consume(TOKEN_COLON, 
"Expected ',' or ':' after 'with' statement");
 
 2098         block(state,blockWidth,
"with");
 
 2102     patchJump(withJump);
 
 2103     emitByte(OP_CLEANUP_WITH);
 
 2109 static void ifStatement(
struct GlobalState * state) {
 
 2121     consume(TOKEN_COLON, 
"Expected ':' after 'if' condition.");
 
 2125     int thenJump = emitJump(OP_POP_JUMP_IF_FALSE);
 
 2129     block(state,blockWidth,
"if");
 
 2135     if (blockWidth == 0 || (check(TOKEN_INDENTATION) && (state->
parser.
current.length == blockWidth))) {
 
 2142         if (match(TOKEN_ELSE) || check(TOKEN_ELIF)) {
 
 2143             int elseJump = emitJump(OP_JUMP);
 
 2144             patchJump(thenJump);
 
 2145             if (state->
parser.
current.type == TOKEN_ELIF || check(TOKEN_IF)) {
 
 2149                 consume(TOKEN_COLON, 
"Expected ':' after 'else'.");
 
 2151                 block(state,blockWidth,
"else");
 
 2154             patchJump(elseJump);
 
 2156         } 
else if (!check(TOKEN_EOF) && !check(TOKEN_EOL)) {
 
 2167     patchJump(thenJump);
 
 2170 static void patchBreaks(
struct GlobalState * state, 
int loopStart) {
 
 2178 static void breakStatement(
struct GlobalState * state) {
 
 2192 static void continueStatement(
struct GlobalState * state) {
 
 2206 static void optionalElse(
struct GlobalState * state, 
size_t blockWidth) {
 
 2209     if (blockWidth == 0 || (check(TOKEN_INDENTATION) && (state->
parser.
current.length == blockWidth))) {
 
 2210         if (blockWidth) advance();
 
 2211         if (match(TOKEN_ELSE)) {
 
 2212             consume(TOKEN_COLON, 
"Expected ':' after 'else'.");
 
 2214             block(state,blockWidth,
"else");
 
 2218             state->
parser = parserBefore;
 
 2223 static void whileStatement(
struct GlobalState * state) {
 
 2227     int loopStart = currentChunk()->count;
 
 2232     if (!(match(TOKEN_TRUE) && match(TOKEN_COLON)) &&
 
 2240         consume(TOKEN_COLON, 
"Expected ':' after 'while' condition.");
 
 2242         exitJump = emitJump(OP_JUMP_IF_FALSE_OR_POP);
 
 2248     block(state,blockWidth,
"while");
 
 2252     emitLoop(state, loopStart, OP_LOOP);
 
 2255         patchJump(exitJump);
 
 2261     optionalElse(state, blockWidth);
 
 2263     patchBreaks(state, loopStart);
 
 2266 static void forStatement(
struct GlobalState * state) {
 
 2276     ssize_t varCount = 0;
 
 2277     int matchedEquals = 0;
 
 2279     if (!check(TOKEN_IDENTIFIER)) {
 
 2280         errorAtCurrent(
"Empty variable list in 'for'");
 
 2285         if (!check(TOKEN_IDENTIFIER)) 
break;
 
 2286         ssize_t ind = parseVariable(state, 
"Expected name for loop iterator.");
 
 2288         if (match(TOKEN_EQUAL)) {
 
 2294         defineVariable(state, ind);
 
 2296         if (check(TOKEN_COMMA)) sawComma = 1;
 
 2297     } 
while (match(TOKEN_COMMA));
 
 2303     if (!matchedEquals && match(TOKEN_IN)) {
 
 2309         anonymousLocal(state);
 
 2310         emitByte(OP_INVOKE_ITER);
 
 2311         loopStart = currentChunk()->count;
 
 2312         exitJump = emitJump(OP_CALL_ITER);
 
 2314         if (varCount > 1 || sawComma) {
 
 2315             EMIT_OPERAND_OP(OP_UNPACK, varCount);
 
 2316             for (ssize_t i = loopInd + varCount - 1; i >= loopInd; i--) {
 
 2317                 EMIT_OPERAND_OP(OP_SET_LOCAL_POP, i);
 
 2320             EMIT_OPERAND_OP(OP_SET_LOCAL_POP, loopInd);
 
 2326         consume(TOKEN_SEMICOLON,
"Expected ';' after C-style loop initializer.");
 
 2327         loopStart = currentChunk()->count;
 
 2332         exitJump = emitJump(OP_JUMP_IF_FALSE_OR_POP);
 
 2334         if (check(TOKEN_SEMICOLON)) {
 
 2336             int bodyJump = emitJump(OP_JUMP);
 
 2337             int incrementStart = currentChunk()->count;
 
 2340                 expressionStatement(state);
 
 2341             } 
while (match(TOKEN_COMMA));
 
 2344             emitLoop(state, loopStart, OP_LOOP);
 
 2345             loopStart = incrementStart;
 
 2346             patchJump(bodyJump);
 
 2350     consume(TOKEN_COLON,
"Expected ':' after loop conditions.");
 
 2355     block(state,blockWidth,
"for");
 
 2359     emitLoop(state, loopStart, isIter ? OP_LOOP_ITER : OP_LOOP);
 
 2360     patchJump(exitJump);
 
 2362     optionalElse(state, blockWidth);
 
 2363     patchBreaks(state, loopStart);
 
 2367 static void returnStatement(
struct GlobalState * state) {
 
 2368     if (check(TOKEN_EOL) || check(TOKEN_EOF)) {
 
 2372             error(
"__init__ may not return a value.");
 
 2375         emitByte(OP_RETURN);
 
 2379 static void tryStatement(
struct GlobalState * state) {
 
 2382     consume(TOKEN_COLON, 
"Expected ':' after 'try'.");
 
 2386     int tryJump = emitJump(OP_PUSH_TRY);
 
 2388     size_t exceptionObject = anonymousLocal(state);
 
 2389     anonymousLocal(state); 
 
 2392     block(state,blockWidth,
"try");
 
 2397 #define EXIT_JUMP_MAX 64 
 2399     int exitJumpOffsets[EXIT_JUMP_MAX] = {0};
 
 2402     exitJumpOffsets[0] = emitJump(OP_JUMP);
 
 2407     exitJumpOffsets[1] = emitJump(OP_ENTER_EXCEPT);
 
 2414     if (blockWidth == 0 || (check(TOKEN_INDENTATION) && (state->
parser.
current.length == blockWidth))) {
 
 2420         if (exitJumps && !firstJump && match(TOKEN_EXCEPT)) {
 
 2421             if (nextJump != -1) {
 
 2422                 patchJump(nextJump);
 
 2425             if (!check(TOKEN_COLON) && !check(TOKEN_AS)) {
 
 2430             nextJump = emitJump(OP_FILTER_EXCEPT);
 
 2434             if (match(TOKEN_AS)) {
 
 2435                 consume(TOKEN_IDENTIFIER, 
"Expected identifier after 'as'.");
 
 2438                 nameInd = renameLocal(state, exceptionObject, state->
parser.
previous);
 
 2443             consume(TOKEN_COLON, 
"Expected ':' after 'except'.");
 
 2445             block(state,blockWidth,
"except");
 
 2451             if (exitJumps < EXIT_JUMP_MAX) {
 
 2452                 exitJumpOffsets[exitJumps++] = emitJump(OP_JUMP);
 
 2454                 error(
"Too many 'except' clauses.");
 
 2458             goto _anotherExcept;
 
 2459         } 
else if (firstJump != 1 && match(TOKEN_ELSE)) {
 
 2460             consume(TOKEN_COLON, 
"Expected ':' after 'else'.");
 
 2461             patchJump(exitJumpOffsets[0]);
 
 2463             emitByte(OP_TRY_ELSE);
 
 2466             block(state, blockWidth, 
"else");
 
 2468             if (nextJump == -1) {
 
 2474             goto _anotherExcept;
 
 2475         } 
else if (match(TOKEN_FINALLY)) {
 
 2476             consume(TOKEN_COLON, 
"Expected ':' after 'finally'.");
 
 2477             for (
int i = firstJump; i < exitJumps; ++i) {
 
 2478                 patchJump(exitJumpOffsets[i]);
 
 2480             if (nextJump != -1) {
 
 2481                 patchJump(nextJump);
 
 2483             emitByte(OP_BEGIN_FINALLY);
 
 2487             block(state,blockWidth,
"finally");
 
 2490             emitByte(OP_END_FINALLY);
 
 2491         } 
else if (!check(TOKEN_EOL) && !check(TOKEN_EOF)) {
 
 2502     for (
int i = firstJump; i < exitJumps; ++i) {
 
 2503         patchJump(exitJumpOffsets[i]);
 
 2506     if (nextJump >= 0) {
 
 2507         patchJump(nextJump);
 
 2508         emitByte(OP_BEGIN_FINALLY);
 
 2509         emitByte(OP_END_FINALLY);
 
 2515 static void raiseStatement(
struct GlobalState * state) {
 
 2518     if (match(TOKEN_FROM)) {
 
 2520         emitByte(OP_RAISE_FROM);
 
 2526 static size_t importModule(
struct GlobalState * state, 
KrkToken * startOfName, 
int leadingDots) {
 
 2530     for (
int i = 0; i < leadingDots; ++i) {
 
 2531         pushStringBuilder(&sb, 
'.');
 
 2534     if (!(leadingDots && check(TOKEN_IMPORT))) {
 
 2535         consume(TOKEN_IDENTIFIER, 
"Expected module name after 'import'.");
 
 2539         while (match(TOKEN_DOT)) {
 
 2541             consume(TOKEN_IDENTIFIER, 
"Expected module path element after '.'");
 
 2547     startOfName->start  = sb.bytes;
 
 2548     startOfName->length = sb.length;
 
 2550     ind = identifierConstant(state, startOfName);
 
 2551     EMIT_OPERAND_OP(OP_IMPORT, ind);
 
 2554     discardStringBuilder(&sb);
 
 2558 static void importStatement(
struct GlobalState * state) {
 
 2562         size_t ind = importModule(state, &startOfName, 0);
 
 2563         if (match(TOKEN_AS)) {
 
 2564             consume(TOKEN_IDENTIFIER, 
"Expected identifier after 'as'.");
 
 2566         } 
else if (startOfName.length != firstName.length) {
 
 2576             ind = identifierConstant(state, &firstName);
 
 2577             EMIT_OPERAND_OP(OP_IMPORT, ind);
 
 2579         declareVariable(state);
 
 2580         defineVariable(state, ind);
 
 2581     } 
while (match(TOKEN_COMMA));
 
 2584 static void optionsImport(
struct GlobalState * state) {
 
 2585     int expectCloseParen = 0;
 
 2587     KrkToken compile_time_builtins = syntheticToken(
"compile_time_builtins");
 
 2588     KrkToken no_implicit_self = syntheticToken(
"no_implicit_self");
 
 2591     consume(TOKEN_IMPORT, 
"__options__ is not a package\n");
 
 2593     if (match(TOKEN_LEFT_PAREN)) {
 
 2594         expectCloseParen = 1;
 
 2595         startEatingWhitespace();
 
 2599         consume(TOKEN_IDENTIFIER, 
"Expected member name");
 
 2602         if (identifiersEqual(&state->
parser.
previous, &compile_time_builtins)) {
 
 2604         } 
else if (identifiersEqual(&state->
parser.
previous, &no_implicit_self)) {
 
 2607             error(
"'%.*s' is not a recognized __options__ import",
 
 2612         if (check(TOKEN_AS)) {
 
 2613             errorAtCurrent(
"__options__ imports can not be given names");
 
 2617     } 
while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_PAREN));
 
 2619     if (expectCloseParen) {
 
 2620         stopEatingWhitespace();
 
 2621         consume(TOKEN_RIGHT_PAREN, 
"Expected ')' after import list started with '('");
 
 2625 static void fromImportStatement(
struct GlobalState * state) {
 
 2626     int expectCloseParen = 0;
 
 2628     int leadingDots = 0;
 
 2630     KrkToken options = syntheticToken(
"__options__");
 
 2631     if (check(TOKEN_IDENTIFIER) && identifiersEqual(&state->
parser.
current, &options)) {
 
 2633         optionsImport(state);
 
 2637     while (match(TOKEN_DOT) || match(TOKEN_ELLIPSIS)) {
 
 2641     importModule(state, &startOfName, leadingDots);
 
 2642     consume(TOKEN_IMPORT, 
"Expected 'import' after module name");
 
 2643     if (match(TOKEN_LEFT_PAREN)) {
 
 2644         expectCloseParen = 1;
 
 2645         startEatingWhitespace();
 
 2648         consume(TOKEN_IDENTIFIER, 
"Expected member name");
 
 2649         size_t member = identifierConstant(state, &state->
parser.
previous);
 
 2650         emitBytes(OP_DUP, 0); 
 
 2651         EMIT_OPERAND_OP(OP_IMPORT_FROM, member);
 
 2652         if (match(TOKEN_AS)) {
 
 2653             consume(TOKEN_IDENTIFIER, 
"Expected identifier after 'as'");
 
 2660         declareVariable(state);
 
 2661         defineVariable(state, member);
 
 2662     } 
while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_PAREN));
 
 2663     if (expectCloseParen) {
 
 2664         stopEatingWhitespace();
 
 2665         consume(TOKEN_RIGHT_PAREN, 
"Expected ')' after import list started with '('");
 
 2670 static void delStatement(
struct GlobalState * state) {
 
 2675             errorAtCurrent(
"Invalid del target");
 
 2677     } 
while (match(TOKEN_COMMA));
 
 2680 static void assertStatement(
struct GlobalState * state) {
 
 2682     int elseJump = emitJump(OP_JUMP_IF_TRUE_OR_POP);
 
 2684     KrkToken assertionError = syntheticToken(
"AssertionError");
 
 2685     size_t ind = identifierConstant(state, &assertionError);
 
 2686     EMIT_OPERAND_OP(OP_GET_GLOBAL, ind);
 
 2689     if (match(TOKEN_COMMA)) {
 
 2694     EMIT_OPERAND_OP(OP_CALL, args);
 
 2697     patchJump(elseJump);
 
 2701 static void errorAfterStatement(
struct GlobalState * state) {
 
 2703         case TOKEN_RIGHT_BRACE:
 
 2704         case TOKEN_RIGHT_PAREN:
 
 2705         case TOKEN_RIGHT_SQUARE:
 
 2706             errorAtCurrent(
"Unmatched '%.*s'",
 
 2709         case TOKEN_IDENTIFIER:
 
 2710             errorAtCurrent(
"Unexpected %.*s after statement.",10,
"identifier");
 
 2713         case TOKEN_BIG_STRING:
 
 2714             errorAtCurrent(
"Unexpected %.*s after statement.",6,
"string");
 
 2717             errorAtCurrent(
"Unexpected %.*s after statement.",
 
 2722 static void simpleStatement(
struct GlobalState * state) {
 
 2723 _anotherSimpleStatement:
 
 2724     if (match(TOKEN_RAISE)) {
 
 2725         raiseStatement(state);
 
 2726     } 
else if (match(TOKEN_RETURN)) {
 
 2727         returnStatement(state);
 
 2728     } 
else if (match(TOKEN_IMPORT)) {
 
 2729         importStatement(state);
 
 2730     } 
else if (match(TOKEN_FROM)) {
 
 2731         fromImportStatement(state);
 
 2732     } 
else if (match(TOKEN_BREAK)) {
 
 2733         breakStatement(state);
 
 2734     } 
else if (match(TOKEN_CONTINUE)) {
 
 2735         continueStatement(state);
 
 2736     } 
else if (match(TOKEN_DEL)) {
 
 2737         delStatement(state);
 
 2738     } 
else if (match(TOKEN_ASSERT)) {
 
 2739         assertStatement(state);
 
 2740     } 
else if (match(TOKEN_PASS)) {
 
 2742     } 
else if (match(TOKEN_LET)) {
 
 2743         letDeclaration(state);
 
 2745         expressionStatement(state);
 
 2747     if (match(TOKEN_SEMICOLON)) 
goto _anotherSimpleStatement;
 
 2748     if (!match(TOKEN_EOL) && !match(TOKEN_EOF)) {
 
 2749         errorAfterStatement(state);
 
 2753 static void statement(
struct GlobalState * state) {
 
 2754     if (match(TOKEN_EOL) || match(TOKEN_EOF)) {
 
 2758     if (check(TOKEN_IF)) {
 
 2760     } 
else if (check(TOKEN_WHILE)) {
 
 2761         whileStatement(state);
 
 2762     } 
else if (check(TOKEN_FOR)) {
 
 2763         forStatement(state);
 
 2764     } 
else if (check(TOKEN_ASYNC)) {
 
 2765         asyncDeclaration(state, 0);
 
 2766     } 
else if (check(TOKEN_TRY)) {
 
 2767         tryStatement(state);
 
 2768     } 
else if (check(TOKEN_WITH)) {
 
 2769         withStatement(state);
 
 2772         simpleStatement(state);
 
 2780         error(
"'yield' outside function");
 
 2784     if (match(TOKEN_FROM)) {
 
 2786         emitByte(OP_INVOKE_ITER);
 
 2788         size_t loopContinue = currentChunk()->count;
 
 2789         size_t exitJump = emitJump(OP_YIELD_FROM);
 
 2791         emitLoop(state, loopContinue, OP_LOOP);
 
 2792         patchJump(exitJump);
 
 2793     } 
else if (check(TOKEN_EOL) || check(TOKEN_EOF) || check(TOKEN_RIGHT_PAREN) || check(TOKEN_RIGHT_BRACE)) {
 
 2800     invalidTarget(state, exprType, 
"yield");
 
 2805         error(
"'await' outside async function");
 
 2810     emitByte(OP_INVOKE_AWAIT);
 
 2812     size_t loopContinue = currentChunk()->count;
 
 2813     size_t exitJump = emitJump(OP_YIELD_FROM);
 
 2815     emitLoop(state, loopContinue, OP_LOOP);
 
 2816     patchJump(exitJump);
 
 2817     invalidTarget(state, exprType, 
"await");
 
 2823     invalidTarget(state, exprType, 
"operator");
 
 2829     invalidTarget(state, exprType, 
"operator");
 
 2830     switch (operatorType) {
 
 2831         case TOKEN_PLUS:  emitByte(OP_POS); 
break;
 
 2832         case TOKEN_MINUS: emitByte(OP_NEGATE); 
break;
 
 2833         case TOKEN_TILDE: emitByte(OP_BITNEGATE); 
break;
 
 2834         case TOKEN_BANG:  emitByte(OP_NOT); 
break;
 
 2839 static int isHex(
int c) {
 
 2840     return (c >= 
'0' && c <= 
'9') || (c >= 
'a' && c <= 
'f') || (c >= 
'A' && c <= 
'F');
 
 2843 static int _pushHex(
struct GlobalState * state, 
int isBytes, 
struct StringBuilder * sb, 
const char *c, 
const char *end, 
size_t n, 
char type) {
 
 2844     char tmpbuf[10] = {0};
 
 2845     for (
size_t i = 0; i < n; ++i) {
 
 2846         if (c + i + 2 == end || !isHex(c[i+2])) {
 
 2847             error(
"truncated \\%c escape", type);
 
 2852     unsigned long value = strtoul(tmpbuf, NULL, 16);
 
 2853     if (value >= 0x110000) {
 
 2854         error(
"invalid codepoint in \\%c escape", type);
 
 2860         unsigned char bytes[5] = {0};
 
 2869 #define PUSH_CHAR(c) krk_pushStringBuilder(&sb, c) 
 2870 #define PUSH_HEX(n, type) _pushHex(state, isBytes, &sb, c, end, n, type) 
 2879     if ((isBytes || isFormat || isRaw) && !(match(TOKEN_STRING) || match(TOKEN_BIG_STRING))) {
 
 2880         error(
"Expected string after prefix? (Internal error - scanner should not have produced this.)");
 
 2884     int formatElements = 0;
 
 2894         int type = state->
parser.
previous.type == TOKEN_BIG_STRING ? 3 : 1;
 
 2900                     case '\\': PUSH_CHAR(
'\\'); 
break;
 
 2901                     case '\'': PUSH_CHAR(
'\''); 
break;
 
 2902                     case '\"': PUSH_CHAR(
'\"'); 
break;
 
 2903                     case 'a': PUSH_CHAR(
'\a'); 
break;
 
 2904                     case 'b': PUSH_CHAR(
'\b'); 
break;
 
 2905                     case 'f': PUSH_CHAR(
'\f'); 
break;
 
 2906                     case 'n': PUSH_CHAR(
'\n'); 
break;
 
 2907                     case 'r': PUSH_CHAR(
'\r'); 
break;
 
 2908                     case 't': PUSH_CHAR(
'\t'); 
break;
 
 2909                     case 'v': PUSH_CHAR(
'\v'); 
break;
 
 2910                     case '[': PUSH_CHAR(
'\033'); 
break;
 
 2935                         if (c[1] >= 
'0' && c[1] <= 
'7') {
 
 2936                             int out = c[1] - 
'0';
 
 2937                             if (c + 2 != end && (c[2] >= 
'0' && c[2] <= 
'7')) {
 
 2941                                 if (c + 1 != end && (c[2] >= 
'0' && c[2] <= 
'7')) {
 
 2951                                 unsigned char bytes[5] = {0};
 
 2953                                 for (
size_t i = 0; i < len; i++) PUSH_CHAR(bytes[i]);
 
 2962             } 
else if (isFormat && *c == 
'}') {
 
 2964                     error(
"single '}' not allowed in f-string");
 
 2970             } 
else if (isFormat && *c == 
'{') {
 
 2980                 const char * start = c+1;
 
 2983                 KrkScanner inner = (
KrkScanner){.start=c+1, .cur=c+1, .linePtr=lineBefore, .line=lineNo, .startOfLine = 0, .hasUnget = 0};
 
 2990                 state->
parser = parserBefore;
 
 2995                 while (*c == 
' ') c++;
 
 2998                     while (*c == 
' ') c++;
 
 3001                     formatType |= FORMAT_OP_EQ;
 
 3008                         formatType |= FORMAT_OP_REPR;
 
 3009                     } 
else if (*c == 
's') {
 
 3010                         formatType |= FORMAT_OP_STR;
 
 3012                         error(
"Unsupported conversion flag '%c' for f-string expression.", *c);
 
 3020                     const char * formatStart = c+1;
 
 3022                     while (c < end && *c != 
'}') c++;
 
 3023                     emitConstant(OBJECT_VAL(
krk_copyString(formatStart,c-formatStart)));
 
 3024                     formatType |= FORMAT_OP_FORMAT;
 
 3028                 if (!(formatType & (FORMAT_OP_FORMAT | FORMAT_OP_STR)) && (formatType & FORMAT_OP_EQ)) {
 
 3029                     formatType |= FORMAT_OP_REPR;
 
 3032                 EMIT_OPERAND_OP(OP_FORMAT_VALUE, formatType);
 
 3035                     error(
"Expected closing '}' after expression in f-string");
 
 3042                 if (*(
unsigned char*)c > 127 && isBytes) {
 
 3043                     error(
"bytes literal can only contain ASCII characters");
 
 3056             if (match(TOKEN_PREFIX_F)) {
 
 3058             } 
else if (match(TOKEN_PREFIX_R)) {
 
 3062     } 
while ((!isBytes || match(TOKEN_PREFIX_B)) && (match(TOKEN_STRING) || match(TOKEN_BIG_STRING)));
 
 3063     if (isBytes && (match(TOKEN_STRING) || match(TOKEN_BIG_STRING))) {
 
 3064         error(
"Can not mix bytes and string literals");
 
 3071     if (sb.length || !formatElements) {
 
 3075     if (formatElements != 1) {
 
 3076         EMIT_OPERAND_OP(OP_MAKE_STRING, formatElements);
 
 3085     for (
size_t i = 0; i < upvalueCount; ++i) {
 
 3087         if ((ssize_t)upvalue->
index == index && upvalue->
isLocal == isLocal) {
 
 3104     for (
size_t i = 0; i < upvalueCount; ++i) {
 
 3105         if (identifiersEqual(name, &compiler->
upvalues[i].
name)) {
 
 3110     if (compiler->
enclosing == NULL) 
return -1;
 
 3112     ssize_t local = resolveLocal(state, compiler->
enclosing, name);
 
 3115         return addUpvalue(state, compiler, local, 1, *name);
 
 3117     ssize_t upvalue = resolveUpvalue(state, compiler->
enclosing, name);
 
 3118     if (upvalue != -1) {
 
 3119         return addUpvalue(state, compiler, upvalue, 0, *name);
 
 3124 #define OP_NONE_LONG -1 
 3125 #define DO_VARIABLE(opset,opget,opdel) do { \ 
 3126     if (exprType == EXPR_ASSIGN_TARGET) { \ 
 3127         if (matchComplexEnd(state)) { \ 
 3128             EMIT_OPERAND_OP(opset, arg); \ 
 3131         exprType = EXPR_NORMAL; \ 
 3133     if (exprType == EXPR_CAN_ASSIGN && match(TOKEN_EQUAL)) { \ 
 3134         parsePrecedence(state, PREC_ASSIGNMENT); \ 
 3135         EMIT_OPERAND_OP(opset, arg); \ 
 3136     } else if (exprType == EXPR_CAN_ASSIGN && matchAssignment(state)) { \ 
 3137         EMIT_OPERAND_OP(opget, arg); \ 
 3138         assignmentValue(state); \ 
 3139         EMIT_OPERAND_OP(opset, arg); \ 
 3140     } else if (exprType == EXPR_DEL_TARGET && checkEndOfDel(state)) {\ 
 3141         if (opdel == OP_NONE) { emitByte(OP_NONE); EMIT_OPERAND_OP(opset, arg); } \ 
 3142         else { EMIT_OPERAND_OP(opdel, arg); } \ 
 3144         EMIT_OPERAND_OP(opget, arg); \ 
 3151         while (properties) {
 
 3152             KrkString * constant = AS_STRING(currentChunk()->constants.values[properties->
ind]);
 
 3153             if (constant->
length == name.length && !memcmp(constant->
chars, name.start, name.length)) {
 
 3154                 ssize_t arg = properties->
ind;
 
 3155                 DO_VARIABLE(OP_SET_NAME, OP_GET_NAME, OP_NONE);
 
 3158             properties = properties->
next;
 
 3161     ssize_t arg = resolveLocal(state, state->
current, &name);
 
 3163         DO_VARIABLE(OP_SET_LOCAL, OP_GET_LOCAL, OP_NONE);
 
 3164     } 
else if ((arg = resolveUpvalue(state, state->
current, &name)) != -1) {
 
 3165         DO_VARIABLE(OP_SET_UPVALUE, OP_GET_UPVALUE, OP_NONE);
 
 3167         if ((state->
current->
optionsFlags & OPTIONS_FLAG_COMPILE_TIME_BUILTINS) && *name.start != 
'_') {
 
 3173                     error(
"Can not assign to '%.*s' when 'compile_time_builtins' is enabled.",
 
 3174                         (
int)name.length, name.start);
 
 3176                     error(
"Can not delete '%.*s' when 'compile_time_builtins' is enabled.",
 
 3177                         (
int)name.length, name.start);
 
 3179                     emitConstant(value);
 
 3184         arg = identifierConstant(state, &name);
 
 3185         DO_VARIABLE(OP_SET_GLOBAL, OP_GET_GLOBAL, OP_DEL_GLOBAL);
 
 3199     consume(TOKEN_LEFT_PAREN, 
"Expected 'super' to be called.");
 
 3202     if (match(TOKEN_RIGHT_PAREN)) {
 
 3204             error(
"super() outside of a method body requires arguments");
 
 3208             error(
"super() is not valid in a function with no arguments");
 
 3212         EMIT_OPERAND_OP(OP_GET_LOCAL, 0);
 
 3215         if (match(TOKEN_COMMA)) {
 
 3220         consume(TOKEN_RIGHT_PAREN, 
"Expected ')' after argument list");
 
 3222     consume(TOKEN_DOT, 
"Expected a field of 'super()' to be referenced.");
 
 3223     consume(TOKEN_IDENTIFIER, 
"Expected a field name.");
 
 3225     EMIT_OPERAND_OP(OP_GET_SUPER, 
ind);
 
 3230     ssize_t varCount = 0;
 
 3232     if (!check(TOKEN_IDENTIFIER)) {
 
 3233         errorAtCurrent(
"Empty variable list in comprehension");
 
 3237         if (!check(TOKEN_IDENTIFIER)) 
break;
 
 3238         defineVariable(state, parseVariable(state, 
"Expected name for iteration variable."));
 
 3241         defineVariable(state, loopInd);
 
 3243         if (check(TOKEN_COMMA)) sawComma = 1;
 
 3244     } 
while (match(TOKEN_COMMA));
 
 3246     consume(TOKEN_IN, 
"Only iterator loops (for ... in ...) are allowed in generator expressions.");
 
 3249     parsePrecedence(state, 
PREC_OR); 
 
 3252     anonymousLocal(state);
 
 3253     emitByte(OP_INVOKE_ITER);
 
 3254     int loopStart = currentChunk()->count;
 
 3255     int exitJump = emitJump(OP_CALL_ITER);
 
 3257     if (varCount > 1 || sawComma) {
 
 3258         EMIT_OPERAND_OP(OP_UNPACK, varCount);
 
 3259         for (ssize_t i = loopInd + varCount - 1; i >= loopInd; i--) {
 
 3260             EMIT_OPERAND_OP(OP_SET_LOCAL_POP, i);
 
 3263         EMIT_OPERAND_OP(OP_SET_LOCAL_POP, loopInd);
 
 3266     if (match(TOKEN_IF)) {
 
 3267         parsePrecedence(state, 
PREC_OR);
 
 3268         int acceptJump = emitJump(OP_JUMP_IF_TRUE_OR_POP);
 
 3269         emitLoop(state, loopStart, OP_LOOP);
 
 3270         patchJump(acceptJump);
 
 3275     if (match(TOKEN_FOR)) {
 
 3276         comprehensionInner(state, scannerBefore, parserBefore, body, arg);
 
 3281         state->
parser = parserBefore;
 
 3286         state->
parser = parserAfter;
 
 3290     emitLoop(state, loopStart, OP_LOOP_ITER);
 
 3291     patchJump(exitJump);
 
 3295 static void yieldInner(
struct GlobalState * state, 
size_t arg) {
 
 3298     emitBytes(OP_YIELD, OP_POP);
 
 3318     comprehensionInner(state, scannerBefore, parserBefore, body, 0);
 
 3322     size_t indFunc = 
krk_addConstant(currentChunk(), OBJECT_VAL(subfunction));
 
 3323     EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
 
 3324     doUpvalues(state, &subcompiler, subfunction);
 
 3325     freeCompiler(&subcompiler);
 
 3326     emitBytes(OP_CALL, 0);
 
 3348     size_t ind = anonymousLocal(state);
 
 3351     comprehensionInner(state, scannerBefore, parserBefore, body, 
ind);
 
 3355     size_t indFunc = 
krk_addConstant(currentChunk(), OBJECT_VAL(subfunction));
 
 3356     EMIT_OPERAND_OP(OP_CLOSURE, indFunc);
 
 3357     doUpvalues(state, &subcompiler, subfunction);
 
 3358     freeCompiler(&subcompiler);
 
 3359     emitBytes(OP_CALL, 0);
 
 3362 static size_t finishStarComma(
struct GlobalState * state, 
size_t arg, 
size_t * argBefore, 
size_t *argAfter) {
 
 3365     EMIT_OPERAND_OP(OP_MAKE_LIST,arg);
 
 3367     emitByte(OP_LIST_EXTEND_TOP);
 
 3369     if (arg == 0 && !check(TOKEN_COMMA)) {
 
 3373         error(
"* expression not valid here");
 
 3379     while (match(TOKEN_COMMA)) {
 
 3381         if (match(TOKEN_ASTERISK)) {
 
 3383             emitByte(OP_LIST_EXTEND_TOP);
 
 3386             emitByte(OP_LIST_APPEND_TOP);
 
 3393     emitByte(OP_TUPLE_FROM_LIST);
 
 3415     int maybeValidAssignment = 0;
 
 3417     size_t argCount = 0;
 
 3418     size_t argAfter = 0;
 
 3419     size_t argBefore = 0;
 
 3422     startEatingWhitespace();
 
 3424     if (check(TOKEN_RIGHT_PAREN)) {
 
 3426         emitBytes(OP_TUPLE,0);
 
 3427     } 
else if (match(TOKEN_ASTERISK)) {
 
 3428         argCount = finishStarComma(state, 0, &argBefore, &argAfter);
 
 3429         maybeValidAssignment = 1;
 
 3432         maybeValidAssignment = 1;
 
 3435         if (match(TOKEN_FOR)) {
 
 3437             maybeValidAssignment = 0;
 
 3438             rewindChunk(currentChunk(), before);
 
 3439             generatorExpression(state, scannerBefore, parserBefore, yieldInner);
 
 3440         } 
else if (match(TOKEN_COMMA)) {
 
 3442             if (!check(TOKEN_RIGHT_PAREN)) {
 
 3445                     if (match(TOKEN_ASTERISK)) {
 
 3446                         argCount = finishStarComma(state, argCount, &argBefore, &argAfter);
 
 3451                 } 
while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_PAREN));
 
 3453             EMIT_OPERAND_OP(OP_TUPLE, argCount);
 
 3458     stopEatingWhitespace();
 
 3460     if (!match(TOKEN_RIGHT_PAREN)) {
 
 3462             case TOKEN_EQUAL: error(
"Assignment value expression must be enclosed in parentheses."); 
break;
 
 3463             default: error(
"Expected ')' at end of parenthesized expression."); 
break;
 
 3469             error(
"Can not assign to empty target list.");
 
 3470         } 
else if (!maybeValidAssignment) {
 
 3471             error(
"Can not assign to generator expression.");
 
 3473             complexAssignment(state, before, scannerBefore, parserBefore, argCount, 1, argBefore, argAfter);
 
 3475     } 
else if (exprType == 
EXPR_ASSIGN_TARGET && (check(TOKEN_EQUAL) || check(TOKEN_COMMA) || check(TOKEN_RIGHT_PAREN))) {
 
 3477             error(
"Can not assign to empty target list.");
 
 3478         } 
else if (!maybeValidAssignment) {
 
 3479             error(
"Can not assign to generator expression.");
 
 3481             rewindChunk(currentChunk(), before);
 
 3482             complexAssignmentTargets(state, scannerBefore, parserBefore, argCount, 2, argBefore, argAfter);
 
 3483             if (!matchComplexEnd(state)) {
 
 3484                 errorAtCurrent(
"Unexpected end of nested target list");
 
 3495 static void listInner(
struct GlobalState * state, 
size_t arg) {
 
 3497     EMIT_OPERAND_OP(OP_LIST_APPEND, arg);
 
 3500 static void finishStarList(
struct GlobalState * state, 
size_t arg) {
 
 3501     EMIT_OPERAND_OP(OP_MAKE_LIST, arg);
 
 3504     emitByte(OP_LIST_EXTEND_TOP);
 
 3506     while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_SQUARE)) {
 
 3507         if (match(TOKEN_ASTERISK)) {
 
 3509             emitByte(OP_LIST_EXTEND_TOP);
 
 3512             emitByte(OP_LIST_APPEND_TOP);
 
 3516     stopEatingWhitespace();
 
 3518     consume(TOKEN_RIGHT_SQUARE,
"Expected ']' at end of list expression.");
 
 3529     startEatingWhitespace();
 
 3531     if (!check(TOKEN_RIGHT_SQUARE)) {
 
 3534         if (match(TOKEN_ASTERISK)) {
 
 3535             finishStarList(state, 0);
 
 3540         if (match(TOKEN_FOR)) {
 
 3542             rewindChunk(currentChunk(), before);
 
 3545             comprehensionExpression(state, scannerBefore, parserBefore, listInner, OP_MAKE_LIST);
 
 3547             size_t argCount = 1;
 
 3548             while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_SQUARE)) {
 
 3549                 if (match(TOKEN_ASTERISK)) {
 
 3550                     finishStarList(state, argCount);
 
 3556             EMIT_OPERAND_OP(OP_MAKE_LIST, argCount);
 
 3560         EMIT_OPERAND_OP(OP_MAKE_LIST, 0);
 
 3563     stopEatingWhitespace();
 
 3565     consume(TOKEN_RIGHT_SQUARE,
"Expected ']' at end of list expression.");
 
 3571 static void dictInner(
struct GlobalState * state, 
size_t arg) {
 
 3573     consume(TOKEN_COLON, 
"Expected ':' after dict key.");
 
 3575     EMIT_OPERAND_OP(OP_DICT_SET, arg);
 
 3581 static void setInner(
struct GlobalState * state, 
size_t arg) {
 
 3583     EMIT_OPERAND_OP(OP_SET_ADD, arg);
 
 3586 static void finishStarSet(
struct GlobalState * state, 
size_t args) {
 
 3587     EMIT_OPERAND_OP(OP_MAKE_SET, args);
 
 3590     emitByte(OP_SET_UPDATE_TOP);
 
 3592     while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_BRACE)) {
 
 3593         if (match(TOKEN_ASTERISK)) {
 
 3595             emitByte(OP_SET_UPDATE_TOP);
 
 3598             emitByte(OP_SET_ADD_TOP);
 
 3602     stopEatingWhitespace();
 
 3603     consume(TOKEN_RIGHT_BRACE,
"Expected '}' at end of dict expression.");
 
 3606 static void finishStarDict(
struct GlobalState * state, 
size_t args) {
 
 3607     EMIT_OPERAND_OP(OP_MAKE_DICT, args);
 
 3610     emitByte(OP_DICT_UPDATE_TOP);
 
 3612     while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_BRACE)) {
 
 3613         if (match(TOKEN_POW)) {
 
 3615             emitByte(OP_DICT_UPDATE_TOP);
 
 3618             consume(TOKEN_COLON, 
"Expected ':' after dict key.");
 
 3620             emitByte(OP_DICT_SET_TOP);
 
 3624     stopEatingWhitespace();
 
 3625     consume(TOKEN_RIGHT_BRACE,
"Expected '}' at end of dict expression.");
 
 3642     startEatingWhitespace();
 
 3644     if (!check(TOKEN_RIGHT_BRACE)) {
 
 3648         if (match(TOKEN_ASTERISK)) {
 
 3649             finishStarSet(state, 0);
 
 3651         } 
else if (match(TOKEN_POW)) {
 
 3652             finishStarDict(state, 0);
 
 3657         if (check(TOKEN_COMMA) || check(TOKEN_RIGHT_BRACE)) {
 
 3659             size_t argCount = 1;
 
 3660             while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_BRACE)) {
 
 3661                 if (match(TOKEN_ASTERISK)) {
 
 3662                     finishStarSet(state, argCount);
 
 3668             EMIT_OPERAND_OP(OP_MAKE_SET, argCount);
 
 3669         } 
else if (match(TOKEN_FOR)) {
 
 3671             rewindChunk(currentChunk(), before);
 
 3673             comprehensionExpression(state, scannerBefore, parserBefore, setInner, OP_MAKE_SET);
 
 3676             consume(TOKEN_COLON, 
"Expected ':' after dict key.");
 
 3679             if (match(TOKEN_FOR)) {
 
 3681                 rewindChunk(currentChunk(), before);
 
 3683                 comprehensionExpression(state, scannerBefore, parserBefore, dictInner, OP_MAKE_DICT);
 
 3690                 size_t argCount = 2;
 
 3691                 while (match(TOKEN_COMMA) && !check(TOKEN_RIGHT_BRACE)) {
 
 3692                     if (match(TOKEN_POW)) {
 
 3693                         finishStarDict(state, argCount);
 
 3697                     consume(TOKEN_COLON, 
"Expected ':' after dict key.");
 
 3701                 EMIT_OPERAND_OP(OP_MAKE_DICT, argCount);
 
 3706         EMIT_OPERAND_OP(OP_MAKE_DICT, 0);
 
 3709     stopEatingWhitespace();
 
 3711     consume(TOKEN_RIGHT_BRACE,
"Expected '}' at end of dict expression.");
 
 3716     rewindChunk(currentChunk(), rewind->
before);
 
 3718     parsePrecedence(state, 
PREC_OR);
 
 3720     int thenJump = emitJump(OP_JUMP_IF_TRUE_OR_POP);
 
 3721     consume(TOKEN_ELSE, 
"Expected 'else' after ternary condition");
 
 3728     int elseJump = emitJump(OP_JUMP);
 
 3729     patchJump(thenJump);
 
 3734     parsePrecedence(state, 
PREC_OR);
 
 3735     patchJump(elseJump);
 
 3737     if (!check(TOKEN_IF)) {
 
 3739         error(
"syntax error");
 
 3743     state->
parser = outParser;
 
 3746 static void complexAssignmentTargets(
struct GlobalState * state, 
KrkScanner oldScanner, 
Parser oldParser, 
size_t targetCount, 
int parenthesized, 
size_t argBefore, 
size_t argAfter) {
 
 3747     emitBytes(OP_DUP, 0);
 
 3750         if (argBefore > 255  || argAfter > 256) {
 
 3751             error(
"Too many assignment targets");
 
 3754         EMIT_OPERAND_OP(OP_UNPACK_EX,((argBefore << 8) | (argAfter-1)));
 
 3756         EMIT_OPERAND_OP(OP_UNPACK,targetCount);
 
 3758     EMIT_OPERAND_OP(OP_REVERSE,targetCount);
 
 3762     state->
parser = oldParser;
 
 3765     size_t checkTargetCount = 0;
 
 3769         if (match(TOKEN_ASTERISK)) {
 
 3771                 errorAtCurrent(
"multiple *expr in assignment");
 
 3779         if (checkTargetCount == targetCount && state->
parser.
previous.type == TOKEN_COMMA) {
 
 3780             if (!match(parenthesized ? TOKEN_RIGHT_PAREN : TOKEN_EQUAL)) {
 
 3781                 goto _errorAtCurrent;
 
 3785         if (checkTargetCount == targetCount && parenthesized) {
 
 3787                 goto _errorAtCurrent;
 
 3791         if (checkTargetCount == targetCount && parenthesized) {
 
 3792             if (parenthesized == 1 && !match(TOKEN_EQUAL)) {
 
 3793                 goto _errorAtCurrent;
 
 3797         if (checkTargetCount == targetCount) 
return;
 
 3799         if (check(TOKEN_COMMA) || check(TOKEN_EQUAL) || check(TOKEN_RIGHT_PAREN)) {
 
 3800             goto _errorAtCurrent;
 
 3806     errorAtCurrent(
"Invalid complex assignment target");
 
 3809 static void complexAssignment(
struct GlobalState * state, 
ChunkRecorder before, 
KrkScanner oldScanner, 
Parser oldParser, 
size_t targetCount, 
int parenthesized, 
size_t argBefore, 
size_t argAfter) {
 
 3811     rewindChunk(currentChunk(), before);
 
 3818     complexAssignmentTargets(state, oldScanner,oldParser,targetCount,parenthesized, argBefore, argAfter);
 
 3822     state->
parser = outParser;
 
 3826     size_t expressionCount = 1;
 
 3827     size_t argBefore = 0;
 
 3828     size_t argAfter = 0;
 
 3831         if (match(TOKEN_ASTERISK)) {
 
 3832             expressionCount = finishStarComma(state, expressionCount, &argBefore, &argAfter);
 
 3838     } 
while (match(TOKEN_COMMA));
 
 3840     EMIT_OPERAND_OP(OP_TUPLE,expressionCount);
 
 3842 _maybeassign: (void)0;
 
 3844         complexAssignment(state, rewind->
before, rewind->
oldScanner, rewind->
oldParser, expressionCount, 0, argBefore, argAfter);
 
 3849     size_t argBefore = 0;
 
 3850     size_t argAfter = 0;
 
 3851     size_t totalArgs = finishStarComma(state,0, &argBefore, &argAfter);
 
 3860     startEatingWhitespace();
 
 3861     size_t argCount = 0, specialArgs = 0, keywordArgs = 0, seenKeywordUnpacking = 0;
 
 3862     if (!check(TOKEN_RIGHT_PAREN)) {
 
 3863         size_t chunkBefore = currentChunk()->count;
 
 3867             if (check(TOKEN_RIGHT_PAREN)) 
break;
 
 3868             if (match(TOKEN_ASTERISK) || check(TOKEN_POW)) {
 
 3870                 if (match(TOKEN_POW)) {
 
 3871                     seenKeywordUnpacking = 1;
 
 3872                     emitBytes(OP_EXPAND_ARGS, 2); 
 
 3876                     if (seenKeywordUnpacking) {
 
 3877                         error(
"Iterable expansion follows keyword argument unpacking.");
 
 3880                     emitBytes(OP_EXPAND_ARGS, 1); 
 
 3885             if (match(TOKEN_IDENTIFIER)) {
 
 3887                 if (check(TOKEN_EQUAL)) {
 
 3891                     size_t ind = identifierConstant(state, &argName);
 
 3892                     EMIT_OPERAND_OP(OP_CONSTANT, 
ind);
 
 3905             } 
else if (seenKeywordUnpacking) {
 
 3906                 error(
"Positional argument follows keyword argument unpacking");
 
 3908             } 
else if (keywordArgs) {
 
 3909                 error(
"Positional argument follows keyword argument");
 
 3913                 emitBytes(OP_EXPAND_ARGS, 0); 
 
 3919             if (argCount == 0 && match(TOKEN_FOR)) {
 
 3920                 currentChunk()->count = chunkBefore;
 
 3921                 generatorExpression(state, scannerBefore, parserBefore, yieldInner);
 
 3923                 if (match(TOKEN_COMMA)) {
 
 3924                     error(
"Generator expression must be parenthesized");
 
 3930         } 
while (match(TOKEN_COMMA));
 
 3932     stopEatingWhitespace();
 
 3933     consume(TOKEN_RIGHT_PAREN, 
"Expected ')' after arguments.");
 
 3941         EMIT_OPERAND_OP(OP_KWARGS, specialArgs);
 
 3948         argCount += 1  + 2 * specialArgs;
 
 3952         EMIT_OPERAND_OP(OP_CALL_METHOD, argCount);
 
 3953     } 
else if (exprType == EXPR_CLASS_PARAMETERS) {
 
 3954         EMIT_OPERAND_OP(OP_CALL, (argCount + 2));
 
 3956         EMIT_OPERAND_OP(OP_CALL, argCount);
 
 3958     writeExpressionLocation(&left,&state->
parser.
previous,&
this,state);
 
 3960     invalidTarget(state, exprType, 
"function call");
 
 3964     int endJump = emitJump(OP_JUMP_IF_FALSE_OR_POP);
 
 3967     invalidTarget(state, exprType, 
"operator");
 
 3971     int endJump = emitJump(OP_JUMP_IF_TRUE_OR_POP);
 
 3972     parsePrecedence(state, 
PREC_OR);
 
 3974     invalidTarget(state, exprType, 
"operator");
 
 3985     if (prefixRule == pstar && precedence > 
PREC_COMMA) prefixRule = NULL;
 
 3987     if (prefixRule == NULL) {
 
 3989             case TOKEN_RIGHT_BRACE:
 
 3990             case TOKEN_RIGHT_PAREN:
 
 3991             case TOKEN_RIGHT_SQUARE:
 
 3992                 error(
"Unmatched '%.*s'",
 
 3997                 error(
"Unexpected end of line");
 
 4000                 error(
"Unexpected end of input");
 
 4003                 error(
"'%.*s' does not start an expression",
 
 4012     prefixRule(state, exprType, &rewind);
 
 4023         infixRule(state, exprType, &rewind);
 
 4027         error(
"Invalid assignment target");
 
 4032 static int maybeSingleExpression(
struct GlobalState * state) {
 
 4044     if (check(TOKEN_STRING) || check(TOKEN_BIG_STRING)) {
 
 4046         if (match(TOKEN_EOL)) {
 
 4049             int isEof = check(TOKEN_EOF);
 
 4057             if (isEof) 
return 1;
 
 4060             KrkToken doc = syntheticToken(
"__doc__");
 
 4061             size_t ind = identifierConstant(state, &doc);
 
 4062             EMIT_OPERAND_OP(OP_DEFINE_GLOBAL, 
ind);
 
 4079         if (match(TOKEN_SEMICOLON)) {
 
 4081             simpleStatement(state);
 
 4087         if (match(TOKEN_EOL) && !check(TOKEN_EOF)) {
 
 4095         if (check(TOKEN_EOF))
 
 4099         errorAfterStatement(state);
 
 4107 void _createAndBind_compilerClass(
void) {
 
 4108     KrkClass * CompilerState = ADD_BASE_CLASS(KRK_BASE_CLASS(CompilerState), 
"CompilerState", KRK_BASE_CLASS(
object));
 
 4110     CompilerState->
_ongcscan = _GlobalState_gcscan;
 
 4111     CompilerState->
_ongcsweep = _GlobalState_gcsweep;
 
 4112     CompilerState->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
 
 4149     if (maybeSingleExpression(state)) {
 
 4153         while (!match(TOKEN_EOF)) {
 
 4157             if (check(TOKEN_EOL) || check(TOKEN_INDENTATION) || check(TOKEN_EOF)) {
 
 4164     freeCompiler(&compiler);
 
 4177 #define RULE(token, a, b, c) [TOKEN_ ## token] = {a, b, c} 
 4193     RULE(LEFT_BRACE,    dict,     NULL,     PREC_NONE),
 
 4194     RULE(RIGHT_PAREN,   NULL,     NULL,     PREC_NONE),
 
 4195     RULE(RIGHT_SQUARE,  NULL,     NULL,     PREC_NONE),
 
 4196     RULE(RIGHT_BRACE,   NULL,     NULL,     PREC_NONE),
 
 4197     RULE(COLON,         NULL,     NULL,     PREC_NONE),
 
 4198     RULE(SEMICOLON,     NULL,     NULL,     PREC_NONE),
 
 4199     RULE(EQUAL,         NULL,     NULL,     PREC_NONE),
 
 4200     RULE(WALRUS,        NULL,     NULL,     PREC_NONE),
 
 4201     RULE(PLUS_EQUAL,    NULL,     NULL,     PREC_NONE),
 
 4202     RULE(MINUS_EQUAL,   NULL,     NULL,     PREC_NONE),
 
 4203     RULE(PLUS_PLUS,     NULL,     NULL,     PREC_NONE),
 
 4204     RULE(MINUS_MINUS,   NULL,     NULL,     PREC_NONE),
 
 4205     RULE(CARET_EQUAL,   NULL,     NULL,     PREC_NONE),
 
 4206     RULE(PIPE_EQUAL,    NULL,     NULL,     PREC_NONE),
 
 4207     RULE(LSHIFT_EQUAL,  NULL,     NULL,     PREC_NONE),
 
 4208     RULE(RSHIFT_EQUAL,  NULL,     NULL,     PREC_NONE),
 
 4209     RULE(AMP_EQUAL,     NULL,     NULL,     PREC_NONE),
 
 4210     RULE(SOLIDUS_EQUAL, NULL,     NULL,     PREC_NONE),
 
 4211     RULE(DSOLIDUS_EQUAL,NULL,     NULL,     PREC_NONE),
 
 4212     RULE(ASTERISK_EQUAL,NULL,     NULL,     PREC_NONE),
 
 4213     RULE(MODULO_EQUAL,  NULL,     NULL,     PREC_NONE),
 
 4214     RULE(AT_EQUAL,      NULL,     NULL,     PREC_NONE),
 
 4215     RULE(POW_EQUAL,     NULL,     NULL,     PREC_NONE),
 
 4216     RULE(ARROW,         NULL,     NULL,     PREC_NONE),
 
 4217     RULE(MINUS,         unary,    binary,   
PREC_SUM),
 
 4218     RULE(PLUS,          unary,    binary,   
PREC_SUM),
 
 4219     RULE(TILDE,         unary,    NULL,     PREC_NONE),
 
 4220     RULE(BANG,          unary,    NULL,     PREC_NONE),
 
 4222     RULE(DOUBLE_SOLIDUS,NULL,     binary,   
PREC_TERM),
 
 4223     RULE(ASTERISK,      pstar,    binary,   
PREC_TERM),
 
 4241     RULE(IDENTIFIER,    variable, NULL,     PREC_NONE),
 
 4242     RULE(STRING,        
string,   NULL,     PREC_NONE),
 
 4243     RULE(BIG_STRING,    
string,   NULL,     PREC_NONE),
 
 4244     RULE(PREFIX_B,      
string,   NULL,     PREC_NONE),
 
 4245     RULE(PREFIX_F,      
string,   NULL,     PREC_NONE),
 
 4246     RULE(PREFIX_R,      
string,   NULL,     PREC_NONE),
 
 4247     RULE(NUMBER,        number,   NULL,     PREC_NONE),
 
 4250     RULE(FALSE,         literal,  NULL,     PREC_NONE),
 
 4251     RULE(NONE,          literal,  NULL,     PREC_NONE),
 
 4252     RULE(TRUE,          literal,  NULL,     PREC_NONE),
 
 4253     RULE(ELLIPSIS,      ellipsis, NULL,     PREC_NONE),
 
 4254     RULE(YIELD,         yield,    NULL,     PREC_NONE),
 
 4255     RULE(AWAIT,         await,    NULL,     PREC_NONE),
 
 4256     RULE(LAMBDA,        lambda,   NULL,     PREC_NONE),
 
 4257     RULE(SUPER,         super_,   NULL,     PREC_NONE),
 
 4258     RULE(CLASS,         NULL,     NULL,     PREC_NONE),
 
 4259     RULE(ELSE,          NULL,     NULL,     PREC_NONE),
 
 4260     RULE(FOR,           NULL,     NULL,     PREC_NONE),
 
 4261     RULE(DEF,           NULL,     NULL,     PREC_NONE),
 
 4262     RULE(DEL,           NULL,     NULL,     PREC_NONE),
 
 4263     RULE(LET,           NULL,     NULL,     PREC_NONE),
 
 4264     RULE(RETURN,        NULL,     NULL,     PREC_NONE),
 
 4265     RULE(WHILE,         NULL,     NULL,     PREC_NONE),
 
 4266     RULE(BREAK,         NULL,     NULL,     PREC_NONE),
 
 4267     RULE(CONTINUE,      NULL,     NULL,     PREC_NONE),
 
 4268     RULE(IMPORT,        NULL,     NULL,     PREC_NONE),
 
 4269     RULE(RAISE,         NULL,     NULL,     PREC_NONE),
 
 4270     RULE(ASYNC,         NULL,     NULL,     PREC_NONE),
 
 4271     RULE(PASS,          NULL,     NULL,     PREC_NONE),
 
 4272     RULE(ASSERT,        NULL,     NULL,     PREC_NONE),
 
 4273     RULE(FINALLY,       NULL,     NULL,     PREC_NONE),
 
 4274     RULE(ELIF,          NULL,     NULL,     PREC_NONE),
 
 4275     RULE(TRY,           NULL,     NULL,     PREC_NONE),
 
 4276     RULE(EXCEPT,        NULL,     NULL,     PREC_NONE),
 
 4277     RULE(AS,            NULL,     NULL,     PREC_NONE),
 
 4278     RULE(FROM,          NULL,     NULL,     PREC_NONE),
 
 4279     RULE(WITH,          NULL,     NULL,     PREC_NONE),
 
 4284     RULE(INDENTATION,   NULL,     NULL,     PREC_NONE),
 
 4285     RULE(ERROR,         NULL,     NULL,     PREC_NONE),
 
 4286     RULE(EOL,           NULL,     NULL,     PREC_NONE),
 
 4287     RULE(EOF,           NULL,     NULL,     PREC_NONE),
 
 4288     RULE(RETRY,         NULL,     NULL,     PREC_NONE),
 
 4291 static ParseRule * getRule(KrkTokenType type) {
 
ParseRule krk_parseRules[]
Parse rules table.
FunctionType
Function compilation type.
ExpressionType
Expression type.
struct Compiler Compiler
Subcompiler state.
KrkCodeObject * krk_compile(const char *src, const char *fileName)
Compile a source string to bytecode.
struct RewindState RewindState
Compiler emit and parse state prior to this expression.
Precedence
Parse precedence ladder.
struct ClassCompiler ClassCompiler
Class compilation context.
void(* ParseFn)(struct GlobalState *, int, struct RewindState *)
Subexpression parser function.
struct ChunkRecorder ChunkRecorder
Bytecode emitter backtracking breadcrumb.
Exported methods for the source compiler.
Functions for debugging bytecode execution.
void krk_disassembleCodeObject(FILE *f, KrkCodeObject *func, const char *name)
Print a disassembly of 'func' to the stream 'f'.
Top-level header with configuration macros.
Functions for dealing with garbage collection and memory allocation.
void krk_markObject(KrkObj *object)
During a GC scan cycle, mark an object as used.
KrkValue krk_parse_float(const char *s, size_t l)
Parse a string into a float.
Struct definitions for core object types.
Definitions used by the token scanner.
void krk_ungetToken(KrkScanner *, KrkToken token)
Push a token back to the scanner to be reprocessed.
KrkToken krk_scanToken(KrkScanner *)
Read the next token from the scanner.
KrkScanner krk_initScanner(const char *src)
Initialize the compiler to scan tokens from 'src'.
KrkScanner krk_tellScanner(KrkScanner *)
Retreive a copy of the current scanner state.
void krk_rewindScanner(KrkScanner *, KrkScanner to)
Rewind the scanner to a previous state.
Bytecode emitter backtracking breadcrumb.
size_t count
Offset into the bytecode.
size_t constants
Number of constants in the constants table.
size_t lines
Offset into the line map.
size_t expressions
Number of expression mapping entries.
Class compilation context.
struct ClassCompiler * enclosing
Enclosing class scope.
int hasAnnotations
Flag indicating if an annotation dictionary has been attached to this class.
KrkToken name
Name of the current class.
size_t continueCount
Number of continue statements.
size_t localNameCapacity
How much space is available in the codeobject's local names table.
struct IndexWithNext * properties
Linked list of class property constant indices.
FunctionType type
Type of function being compiled.
size_t continueSpace
Space in continues array.
size_t optionsFlags
Special options imports; similar to future in Python.
size_t localsSpace
Space in the locals array.
int delSatisfied
Flag indicating if a 'del' target has been completed.
struct Compiler * enclosed
Subcompiler we are enclosing, need for type annotation compilation.
size_t loopLocalCount
Tracks how many locals to pop off the stack when exiting a loop.
size_t localCount
Total number of local variables.
size_t scopeDepth
Depth of nested scope blocks.
size_t breakSpace
Space in breaks array.
size_t upvaluesSpace
Space in the upvalues array.
Local * locals
Array of local variable references.
struct LoopExit * continues
Array of loop exit instruction indices for continue statements.
struct LoopExit * breaks
Array of loop exit instruction indices for break statements.
size_t annotationCount
Number of type annotations found while compiling function signature.
KrkCodeObject * codeobject
Bytecode emitter.
size_t breakCount
Number of break statements.
struct Compiler * enclosing
Enclosing function compiler, or NULL for a module.
Upvalue * upvalues
Array of upvalue references. Count is stored in the codeobject.
int unnamedArgs
Number of positional arguments that will not be assignable through keywords.
KrkScanner scanner
Scanner state.
Parser parser
Parser state.
ClassCompiler * currentClass
Current in-progress class definition (or NULL)
Compiler * current
Current compiler (in-progress code object) state.
KrkInstance inst
Base instance.
size_t ind
Index of an identifier constant.
struct IndexWithNext * next
Linked list next pointer.
Opcode chunk of a code object.
size_t krk_writeConstant(KrkChunk *chunk, KrkValue value, size_t line)
Add a new constant and write an instruction for it.
size_t krk_addConstant(KrkChunk *chunk, KrkValue value)
Add a new constant value to an opcode chunk.
void krk_writeChunk(KrkChunk *chunk, uint8_t byte, size_t line)
Append a byte to an opcode chunk.
KrkCleanupCallback _ongcsweep
C function to call when the garbage collector is discarding an instance of this class.
KrkCleanupCallback _ongcscan
C function to call when the garbage collector visits an instance of this class in the scan phase.
size_t allocSize
Size to allocate when creating instances of this class.
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
unsigned short potentialPositionals
Precalculated positional arguments for complex argument processing.
size_t overlongJumpsCount
Number of entries in pessimal jump table.
KrkChunk chunk
Bytecode data.
size_t upvalueCount
Number of upvalues this function collects as a closure.
void krk_debug_addExpression(KrkCodeObject *codeobject, uint8_t start, uint8_t midStart, uint8_t midEnd, uint8_t end)
Add an expression mapping to the bytecode chunk.
KrkLocalEntry * localNames
Stores the names of local variables used in the function, for debugging.
unsigned short keywordArgs
Arity of keyword (default) arguments.
KrkOverlongJump * overlongJumps
Pessimal overlong jump container.
unsigned short requiredArgs
Arity of required (non-default) arguments.
KrkString * docstring
Docstring attached to the function.
KrkCodeObject * krk_newCodeObject(void)
Create a new, uninitialized code object.
size_t localNameCount
Number of entries in localNames.
KrkString * name
Name of the function.
size_t overlongJumpsCapacity
Number of possible entries in pessimal jump table.
KrkString * qualname
The dotted name of the function.
Map entry of opcode offsets to expressions spans.
KrkInstance * krk_newInstance(KrkClass *_class)
Create a new instance of the given class.
KrkTable fields
Attributes table.
Map entry of instruction offsets to line numbers.
Metadata on a local variable name in a function.
size_t birthday
Instruction offset that this local name became valid on.
KrkString * name
Name of the local.
size_t id
Local ID as used by opcodes; offset from the frame's stack base.
size_t deathday
Instruction offset that this local name becomes invalid on.
The most basic object type.
uint16_t flags
General object flags, mostly related to garbage collection.
uint16_t intendedTarget
High bytes of the intended target.
uint8_t originalOpcode
Original jump opcode to execute.
uint32_t instructionOffset
Instruction (operand offset) this jump target applies to.
Immutable sequence of Unicode codepoints.
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
char * chars
UTF8 canonical data.
size_t length
String length in bytes.
size_t krk_codepointToBytes(krk_integer_type value, unsigned char *out)
Convert an integer codepoint to a UTF-8 byte representation.
int krk_tableGet(KrkTable *table, KrkValue key, KrkValue *value)
Obtain the value associated with a key in a table.
void krk_attachNamedObject(KrkTable *table, const char name[], KrkObj *obj)
Attach an object to an attribute table.
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
int krk_tableGet_fast(KrkTable *table, struct KrkString *str, KrkValue *value)
Obtain the value associated with a string key in a table.
KrkValue currentException
A token from the scanner.
void krk_writeValueArray(KrkValueArray *array, KrkValue value)
Add a value to a value array.
Stack reference or primative value.
Local variable reference.
KrkToken name
Token that provided the name for this variable.
ssize_t depth
Stack depth, or -1 if uninitialized.
char isCaptured
Flag indicating if the variable is captured by a closure.
Tracks 'break' and 'continue' statements.
KrkToken token
Token for this exit statement, so its location can be printed in an error message.
int offset
Offset of the jump expression to patch.
ParseFn infix
Parse function to call when this token appears after an expression.
Precedence precedence
Precedence ordering for Pratt parsing, Precedence.
ParseFn prefix
Parse function to call when this token appears at the start of an expression.
KrkToken previous
Last token matched, consumed, or advanced over.
KrkToken current
Token to be parsed.
unsigned int eatingWhitespace
Depth of whitespace-ignoring parse functions.
char hadError
Flag indicating if the parser encountered an error.
Compiler emit and parse state prior to this expression.
ChunkRecorder before
Bytecode and constant table output offsets.
Parser oldParser
Previous/current tokens.
KrkScanner oldScanner
Scanner cursor state.
Inline flexible string array.
Closure upvalue reference.
char isLocal
Flag indicating if Kuroko Language Reference is a local or upvalue index.
KrkToken name
Name for direct lookup. Mainly for non-automatically-populated upvalue cells.
size_t index
Enclosing local index or upvalue index.
Utilities for creating native bindings.
void krk_pushStringBuilderStr(struct StringBuilder *sb, const char *str, size_t len)
Append a string to the end of a string builder.
KrkValue krk_finishStringBuilderBytes(struct StringBuilder *sb)
Finalize a string builder in a bytes object.
KrkValue krk_discardStringBuilder(struct StringBuilder *sb)
Discard the contents of a string builder.
KrkValue krk_finishStringBuilder(struct StringBuilder *sb)
Finalize a string builder into a string object.
void krk_pushStringBuilder(struct StringBuilder *sb, char c)
Add a character to the end of a string builder.
Core API for the bytecode virtual machine.
krk_threadLocal KrkThreadState krk_currentThread
Thread-local VM state.
#define vm
Convenience macro for namespacing.
KrkValue krk_pop(void)
Pop the top of the stack.
void krk_push(KrkValue value)
Push a stack value.