exprtree* make_for (scanner_ident_t *counter_name_ident, exprtree *counter_init, exprtree *start, exprtree *end, exprtree *body) { scanner_region_t region = counter_name_ident->region; if (start->result.length != 1 || end->result.length != 1 || start->result.number != end->result.number) { sprintf(error_string, _("The start and end of a for loop interval must be tuples of the same tag and length 1.")); error_region = region; JUMP(1); } else { char end_name_buf[MAX_GENSYM_LEN]; char *end_name = gensym(end_name_buf); scanner_ident_t *end_name_ident = scanner_make_ident(scanner_null_region, end_name); exprtree *end_init = make_assignment(end_name_ident, end); exprtree *init = make_sequence(counter_init, end_init); exprtree *inc = make_assignment(counter_name_ident, make_function_from_string("__add", exprlist_append(make_var(counter_name_ident), make_int_number(1, scanner_null_region)), scanner_null_region)); exprtree *invariant = make_function_from_string("__lessequal", exprlist_append(make_var(counter_name_ident), make_var(end_name_ident)), scanner_null_region); free(end_name_ident); return make_sequence(init, make_while(invariant, make_sequence(body, inc))); } }
int Parser::expression(int pos, int status) { int isputs = 0; if(tok.skip("$")) { // global varibale if(is_asgmt()) asgmt(); } else if(tok.skip("require")) { make_require(); } else if(tok.skip("def")) { blocksCount++; make_func(); } else if(tok.skip("module")) { blocksCount++; module = tok.tok[tok.pos++].val; eval(0, NON); module = ""; } else if(funcs.inside == false && !tok.is("def", 1) && !tok.is("module", 1) && !tok.is("$", 1) && !tok.is(";", 1) && module == "") { // main func entry funcs.inside = true; funcs.now++; funcs.append("main", ntv.count, 0); // append funcs ntv.genas("push ebp"); ntv.genas("mov ebp esp"); uint32_t espBgn = ntv.count + 2; ntv.genas("sub esp 0"); ntv.gencode(0x8b); ntv.gencode(0x75); ntv.gencode(0x0c); // mov esi, 0xc(%ebp) eval(0, BLOCK_NORMAL); ntv.gencode(0x81); ntv.gencode(0xc4); ntv.gencode_int32(ADDR_SIZE * (var.focus().size() + 6)); // add %esp nn ntv.gencode(0xc9);// leave ntv.gencode(0xc3);// ret ntv.gencode_int32_insert(ADDR_SIZE * (var.focus().size() + 6), espBgn); funcs.inside = false; } else if(is_asgmt()) { asgmt(); } else if((isputs=tok.skip("puts")) || tok.skip("print")) { do { ExprType et = expr_entry(); ntv.genas("push eax"); if(et.is_type(T_STRING)) { ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(4);// call *0x04(esi) putString } else { ntv.gencode(0xff); ntv.gencode(0x16); // call (esi) putNumber } ntv.genas("add esp 4"); } while(tok.skip(",")); // for new line if(isputs) { ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(8);// call *0x08(esi) putLN } } else if(tok.skip("for")) { blocksCount++; asgmt(); if(!tok.skip(",")) error("error: %d: expected ','", tok.tok[tok.pos].nline); make_while(); } else if(tok.skip("while")) { blocksCount++; make_while(); } else if(tok.skip("return")) { make_return(); } else if(tok.skip("if")) { blocksCount++; make_if(); } else if(tok.skip("else")) { uint32_t end; ntv.gencode(0xe9); end = ntv.count; ntv.gencode_int32(0);// jmp while end ntv.gencode_int32_insert(ntv.count - pos - 4, pos); eval(end, BLOCK_NORMAL); return 1; } else if(tok.skip("elsif")) { uint32_t endif, end; ntv.gencode(0xe9); endif = ntv.count; ntv.gencode_int32(0);// jmp while end ntv.gencode_int32_insert(ntv.count - pos - 4, pos); expr_entry(); // if condition ntv.gencode(0x83); ntv.gencode(0xf8); ntv.gencode(0x00);// cmp eax, 0 ntv.gencode(0x75); ntv.gencode(0x05); // jne 5 tok.skip(";"); ntv.gencode(0xe9); end = ntv.count; ntv.gencode_int32(0);// jmp while end eval(end, BLOCK_NORMAL); ntv.gencode_int32_insert(ntv.count - endif - 4, endif); return 1; } else if(tok.skip("break")) { make_break(); } else if(tok.skip("end")) { blocksCount--; if(status == NON) return 1; if(status == BLOCK_NORMAL) { ntv.gencode_int32_insert(ntv.count - pos - 4, pos); } else if(status == BLOCK_FUNC) funcs.inside = false; return 1; } else if(!tok.skip(";")) { expr_entry(); } return 0; }