very basic while loop
This commit is contained in:
		| @@ -1,15 +1,4 @@ | ||||
| a := 0 | ||||
| { | ||||
| 	a := 1 | ||||
| 	b := a | ||||
| } | ||||
|  | ||||
| //a := 1 | ||||
| //b := 1 - 2 * 2 + 5 | ||||
| //c := a + b * 2 * b | ||||
| //d := a + 4 * b * a | ||||
|  | ||||
| /*x := 1 | ||||
| x := 1 | ||||
| y := 1 | ||||
|  | ||||
| i := 60 | ||||
| @@ -17,6 +6,6 @@ while i { | ||||
| 	z := x + y | ||||
| 	y = x | ||||
| 	x = z | ||||
| 	print(z) | ||||
| 	//print(z) | ||||
| 	i = i - 1 | ||||
| }*/ | ||||
| } | ||||
|   | ||||
							
								
								
									
										6
									
								
								ir.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								ir.c
									
									
									
									
									
								
							| @@ -69,6 +69,7 @@ static void print_irparam(const IRParam *p) { | ||||
|  | ||||
| void print_ir(IRToks *v) { | ||||
| 	for (size_t i = 0; i < v->len; i++) { | ||||
| 		printf("%04zx ", i); | ||||
| 		printf("%s", irinstr_str[v->toks[i].instr]); | ||||
| 		switch (v->toks[i].instr) { | ||||
| 			case IRSet: | ||||
| @@ -92,13 +93,12 @@ void print_ir(IRToks *v) { | ||||
| 				} | ||||
| 				break; | ||||
| 			case IRJmp: | ||||
| 				printf(" "); | ||||
| 				printf(" %zu", v->toks[i].Jmp.iaddr); | ||||
| 				printf(" %zx", v->toks[i].Jmp.iaddr); | ||||
| 				break; | ||||
| 			case IRJnz: | ||||
| 				printf(" "); | ||||
| 				print_irparam(&v->toks[i].CJmp.condition); | ||||
| 				printf(" %zu", v->toks[i].CJmp.iaddr); | ||||
| 				printf(" %zx", v->toks[i].CJmp.iaddr); | ||||
| 				break; | ||||
| 			default: | ||||
| 				break; | ||||
|   | ||||
							
								
								
									
										59
									
								
								parse.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								parse.c
									
									
									
									
									
								
							| @@ -356,9 +356,66 @@ static void stmt(State *s, Scope *sc, TokListItem *t) { | ||||
| 				if (t->next->tok.Op == OpRCurl) | ||||
| 					break; | ||||
| 			} | ||||
| 			TRY(stmt(s, &inner_sc, t->next)); | ||||
| 			TRY_ELSE(stmt(s, &inner_sc, t->next), term_scope(&inner_sc)); | ||||
| 		} | ||||
| 		term_scope(&inner_sc); | ||||
| 		t = t->next; | ||||
| 	} else if (t->tok.kind == TokWhile) { | ||||
| 		/* How while is generally implemented in IR:  | ||||
| 		 * 0: jmp to 3 | ||||
| 		 * 1: some_code | ||||
| 		 * 2: some_code | ||||
| 		 * 3: some stuff evaluating condition xyz | ||||
| 		 * 4: jmp to 1 if condition xyz is met | ||||
| 		 * */ | ||||
|  | ||||
| 		size_t jmp_instr_iaddr = s->ir->len; | ||||
| 		irtoks_app(s->ir, (IRTok){ | ||||
| 			.ln = t->tok.ln, | ||||
| 			.col = t->tok.col, | ||||
| 			.instr = IRJmp, | ||||
| 			.Jmp = { | ||||
| 				.iaddr = 0, /* unknown for now */ | ||||
| 			}, | ||||
| 		}); | ||||
|  | ||||
| 		t = t->next; | ||||
|  | ||||
| 		/* find beginning of while loop body */ | ||||
| 		TokListItem *lcurl; | ||||
| 		for (TokListItem *i = t;; i++) { | ||||
| 			if (i == NULL) { | ||||
| 				mark_err(&start->tok); | ||||
| 				set_err("Expected '{' after 'while' loop condition"); | ||||
| 				return; | ||||
| 			} | ||||
| 			if (i->tok.kind == TokOp && i->tok.Op == OpLCurl) { | ||||
| 				lcurl = i; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		/* write loop body to IR stream */ | ||||
| 		TRY(stmt(s, sc, lcurl)); | ||||
|  | ||||
| 		/* finally we know where the jmp from the beginning has to jump to */ | ||||
| 		s->ir->toks[jmp_instr_iaddr].Jmp.iaddr = s->ir->len; | ||||
|  | ||||
| 		size_t addr = sc->mem_addr++; | ||||
| 		TRY(expr(s, sc, t, true, true, addr)); | ||||
|  | ||||
| 		irtoks_app(s->ir, (IRTok){ | ||||
| 			.ln = t->tok.ln, | ||||
| 			.col = t->tok.col, | ||||
| 			.instr = IRJnz, | ||||
| 			.CJmp = { | ||||
| 				.iaddr = jmp_instr_iaddr + 1, | ||||
| 				.condition = { | ||||
| 					.kind = IRParamAddr, | ||||
| 					.Addr = addr, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}); | ||||
| 	} | ||||
| 	toklist_del(s->toks, start, t); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user