diff --git a/compiler.c b/compiler.c index 1613e8d..c3a643e 100644 --- a/compiler.c +++ b/compiler.c @@ -443,6 +443,18 @@ static void block(int indentation) { declaration(); if (check(TOKEN_EOL)) endOfLine(); } while (check(TOKEN_INDENTATION)); +#ifdef ENABLE_DEBUGGING + if (vm.enableDebugging) { + fprintf(stderr, "On line %d, ", (int)parser.current.line); + if (check(TOKEN_INDENTATION)) { + fprintf(stderr, "Exiting block from %d to %d\n", + (int)currentIndentation, (int)parser.current.length); + } else { + fprintf(stderr, "Exiting block from %d to something that isn't indentation.\n", + (int)currentIndentation); + } + } +#endif } else { errorAtCurrent("Expected indentation for block"); } @@ -691,26 +703,71 @@ static void forStatement() { /* For now this is going to be kinda broken */ beginScope(); - /* actually should be `for NAME in ITERABLE` ... */ + ssize_t loopInd = current->localCount; varDeclaration(); - consume(TOKEN_COMMA,"expect ,"); + int loopStart; + int exitJump; - int loopStart = currentChunk()->count; - expression(); /* condition */ - int exitJump = emitJump(OP_JUMP_IF_FALSE); - emitByte(OP_POP); + if (match(TOKEN_IN)) { + defineVariable(loopInd); - if (check(TOKEN_COMMA)) { - advance(); - int bodyJump = emitJump(OP_JUMP); - int incrementStart = currentChunk()->count; + KrkToken _it = syntheticToken("__loop_iter"); + KrkToken _iter = syntheticToken("__iter__"); + size_t indLoopIter, indIterCall; + + /* __loop_iter = */ + indLoopIter = current->localCount; + addLocal(_it); + defineVariable(indLoopIter); + + /* ITERABLE.__iter__() */ expression(); + ssize_t ind = identifierConstant(&_iter); + EMIT_CONSTANT_OP(OP_GET_PROPERTY, ind); + emitBytes(OP_CALL, 0); + + /* assign */ + EMIT_CONSTANT_OP(OP_SET_LOCAL, indLoopIter); + + /* LOOP STARTS HERE */ + loopStart = currentChunk()->count; + emitByte(0xFF); + + /* Call the iterator */ + EMIT_CONSTANT_OP(OP_GET_LOCAL, indLoopIter); + emitBytes(OP_CALL, 0); + + /* Assign the result to our loop index */ + EMIT_CONSTANT_OP(OP_SET_LOCAL, loopInd); + + /* Get the loop iterator again */ + EMIT_CONSTANT_OP(OP_GET_LOCAL, indLoopIter); + emitByte(OP_EQUAL); + emitByte(OP_NOT); + exitJump = emitJump(OP_JUMP_IF_FALSE); emitByte(OP_POP); - emitLoop(loopStart); - loopStart = incrementStart; - patchJump(bodyJump); + } else { + consume(TOKEN_COMMA,"expect ,"); + loopStart = currentChunk()->count; + + + expression(); /* condition */ + exitJump = emitJump(OP_JUMP_IF_FALSE); + emitByte(OP_POP); + + if (check(TOKEN_COMMA)) { + advance(); + int bodyJump = emitJump(OP_JUMP); + int incrementStart = currentChunk()->count; + expression(); + emitByte(OP_POP); + + emitLoop(loopStart); + loopStart = incrementStart; + patchJump(bodyJump); + } } consume(TOKEN_COLON,"expect :"); diff --git a/rline.c b/rline.c index c9a98f2..9f2760d 100644 --- a/rline.c +++ b/rline.c @@ -749,12 +749,12 @@ int syn_py_calculate(struct syntax_state * state) { case 0: if (charat() == '#') { paint_comment(state); - } else if (state->i == 0 && match_and_paint(state, "import", FLAG_PRAGMA, c_keyword_qualifier)) { - return 0; +#if 0 } else if (charat() == '@') { paint(1, FLAG_PRAGMA); while (c_keyword_qualifier(charat())) paint(1, FLAG_PRAGMA); return 0; +#endif } else if (charat() == '"') { if (nextchar() == '"' && charrel(2) == '"') { paint(3, FLAG_STRING); diff --git a/system.krk b/system.krk index faa2460..367025a 100644 --- a/system.krk +++ b/system.krk @@ -36,11 +36,44 @@ class List: base = base + ", " base = base + self._get(self._list,i) return base + "]" + def __iter__(self): + let me = self + def makeIter(ind): + let l = me + let len = l.length() + let i = ind + def iter(): + if i >= len: + return iter + let out = l[i] + i = i + 1 + return out + return iter + return makeIter(0) + +class Range: + def __init__(self, min, max): + self.min = min + self.max = max + def __iter__(self): + let me = self + def makeIter(ind): + let l = me + let i = ind + def iter(): + if i >= l.max: + return iter + let out = i + i = i + 1 + return out + return iter + return makeIter(self.min) let module = SystemModule() module.sleep = __krk_builtin_sleep module.HashMap = HashMap module.List = List +module.Range = Range return module diff --git a/testList.krk b/testList.krk new file mode 100644 index 0000000..bcd6e28 --- /dev/null +++ b/testList.krk @@ -0,0 +1,13 @@ +import system + +let l = system.List() + +l.append(1) +l.append(2) +l.append("string") +l.append(3.14159) + +for v in l: + print v + +return 0 diff --git a/value.c b/value.c index 63bb674..ef2fe51 100644 --- a/value.c +++ b/value.c @@ -49,7 +49,9 @@ int krk_valuesEqual(KrkValue a, KrkValue b) { case VAL_FLOATING: return AS_FLOATING(a) == AS_FLOATING(b); case VAL_OBJECT: { if (IS_STRING(a) && IS_STRING(b)) return AS_OBJECT(a) == AS_OBJECT(b); - /* otherwise we need to do... fun stuff (push, call compare, etc.)*/ + /* If their pointers are equal, assume they are always equivalent */ + if (AS_OBJECT(a) == AS_OBJECT(b)) return 1; + /* TODO: __eq__ */ return 0; } default: return 0;