Beispiel #1
0
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)));
    }
}
Beispiel #2
0
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;
}