Add support for iterators
This commit is contained in:
parent
1d3368861b
commit
0f508c38dc
83
compiler.c
83
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 :");
|
||||
|
4
rline.c
4
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);
|
||||
|
33
system.krk
33
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
|
||||
|
13
testList.krk
Normal file
13
testList.krk
Normal file
@ -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
|
4
value.c
4
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;
|
||||
|
Loading…
Reference in New Issue
Block a user