<commit_before>#include "expr.h"

extern char *module;
extern int ntvCount;
extern unsigned char *ntvCode;

int is_string_tok() { return tok.tok[tok.pos].type == TOK_STRING; }
int is_number_tok() { return tok.tok[tok.pos].type == TOK_NUMBER; }
int is_ident_tok()  { return tok.tok[tok.pos].type == TOK_IDENT;  }

int expr_entry() { return expr_compare(); }

int32_t expr_compare() {
	int andop=0, orop=0;
	expr_logic();
	while((andop=skip("and") || skip("&")) || (orop=skip("or") || skip("|")) || skip("xor") || skip("^")) {
		genas("push eax");
		expr_logic();
		genas("mov ebx eax");
		genas("pop eax");
		gencode(andop ? 0x21 : orop ? 0x09 : 0x31); gencode(0xd8); // and eax ebx
	}

	return 0;
}

int expr_logic() {
	int32_t lt=0, gt=0, ne=0, eql=0, fle=0;
	expr_add_sub();
	if((lt=skip("<")) || (gt=skip(">")) || (ne=skip("!=")) ||
			(eql=skip("==")) || (fle=skip("<=")) || skip(">=")) {
		genas("push eax");
		expr_add_sub();
		genas("mov ebx eax");
		genas("pop eax");
		gencode(0x39); gencode(0xd8); // cmp %eax, %ebx
		/*
		 * < setl 0x9c
		 * > setg 0x9f
		 * <= setle 0x9e
		 * >= setge 0x9d
		 * == sete 0x94
		 * != setne 0x95
		 */
		gencode(0x0f); gencode(lt ? 0x9c : gt ? 0x9f : ne ? 0x95 : eql ? 0x94 : fle ? 0x9e : 0x9d); gencode(0xc0); // setX al
		gencode(0x0f); gencode(0xb6); gencode(0xc0); // movzx eax al
	}

	return 0;
}

int expr_add_sub() {
	int add;
	expr_mul_div();
	while((add = skip("+")) || skip("-")) {
		genas("push eax");
		expr_mul_div();
		genas("mov ebx eax");  // mov %ebx %eax
		genas("pop eax");
		if(add) { genas("add eax ebx"); }// add %eax %ebx
		else { genas("sub eax ebx"); } // sub %eax %ebx
	}
	return 0;
}

int expr_mul_div() {
	int mul, div;
	expr_primary();
	while((mul = skip("*")) || (div=skip("/")) || skip("%")) {
		genas("push eax");
		expr_primary();
		genas("mov ebx eax"); // mov %ebx %eax
		genas("pop eax");
		if(mul) {
			genas("mul ebx");
		} else if(div) {
			genas("mov edx 0");
			genas("div ebx");
		} else { //mod
			genas("mov edx 0");
			genas("div ebx");
			genas("mov eax edx");
		}
	}
	return 0;
}

int expr_primary() {
	int is_get_addr = 0, ispare = 0;

	if(skip("&")) is_get_addr = 1;

	if(is_number_tok()) { // number?
		genas("mov eax %d", atoi(tok.tok[tok.pos++].val));
	} else if(skip("'")) { // char?
		genas("mov eax %d", tok.tok[tok.pos++].val[0]);
		skip("'");
	} else if(is_string_tok()) { // string?
		gencode(0xb8); get_string();
		gencode_int32(0x00); // mov eax string_address
	} else if(is_ident_tok()) { // variable or inc or dec
		char *name = tok.tok[tok.pos].val, *mod_name = "";
		Variable *v; 

		if(streql(tok.tok[tok.pos + 1].val, ".")) { // module?
			mod_name = tok.tok[tok.pos++].val; 
			skip(".");
			name = tok.tok[tok.pos].val; 
		}

		if(is_asgmt()) {
			asgmt();
		} else {
			SKIP_TOK;
			if(skip("[")) { // Array?
				v = get_var(name , mod_name);
				if(v == NULL) v = get_var(name, module);
				if(v == NULL)
					error("error: %d: '%s' was not declare", tok.tok[tok.pos].nline, name);
				expr_entry();
				genas("mov ecx eax");

				if(v->loctype == V_LOCAL) {
					gencode(0x8b); gencode(0x55); gencode(256 - ADDR_SIZE * v->id); // mov edx, [ebp - v*4]
				} else if(v->loctype == V_GLOBAL) {
					gencode(0x8b); gencode(0x15); gencode_int32(v->id); // mov edx, GLOBAL_ADDR
				}

				if(v->type == T_INT) {
					gencode(0x8b); gencode(0x04); gencode(0x8a);// mov eax, [edx + ecx * 4]
				} else {
					gencode(0x0f); gencode(0xb6); gencode(0x04); gencode(0x0a);// movzx eax, [edx + ecx]
				}

				if(!skip("]"))
					error("error: %d: expected expression ']'", tok.tok[tok.pos].nline);
			} else if((ispare = skip("(")) || is_stdfunc(name, mod_name) || get_func(name, mod_name)) { // Function?
				int is_stdfunc = make_stdfunc(name, mod_name);
				int is_lib = is_lib_module(mod_name);

				if(is_lib) { // library function
					size_t params = 0;
					if(is_number_tok() || is_ident_tok() || 
							is_string_tok() || streql(tok.tok[tok.pos].val, "(")) { // has arg?
						for(int i = tok.pos; !streql(tok.tok[i].val, ")"); i++) 
							params += streql(tok.tok[i].val, ","); // count params
						params++;
						for(int i = 0; i < params; i++) {
							expr_entry();
							gencode(0x89); gencode(0x44); gencode(0x24); gencode(i * ADDR_SIZE);
							if(i < params - 1 && !skip(","))
								error("error: %d: expected ','", tok.tok[tok.pos].nline);
						} 
					}
					gencode(0xe8); gencode_int32(call_lib_func(name, mod_name) - (uint32_t)&ntvCode[ntvCount] - 4); // call func
				} else if(!is_stdfunc) {	// user function<commit_msg>delete waste code<commit_after>#include "expr.h"

extern char *module;
extern int ntvCount;
extern unsigned char *ntvCode;

int is_string_tok() { return tok.tok[tok.pos].type == TOK_STRING; }
int is_number_tok() { return tok.tok[tok.pos].type == TOK_NUMBER; }
int is_ident_tok()  { return tok.tok[tok.pos].type == TOK_IDENT;  }

int expr_entry() { return expr_compare(); }

int32_t expr_compare() {
	int andop=0, orop=0;
	expr_logic();
	while((andop=skip("and") || skip("&")) || (orop=skip("or") || skip("|")) || skip("xor") || skip("^")) {
		genas("push eax");
		expr_logic();
		genas("mov ebx eax");
		genas("pop eax");
		gencode(andop ? 0x21 : orop ? 0x09 : 0x31); gencode(0xd8); // and eax ebx
	}

	return 0;
}

int expr_logic() {
	int32_t lt=0, gt=0, ne=0, eql=0, fle=0;
	expr_add_sub();
	if((lt=skip("<")) || (gt=skip(">")) || (ne=skip("!=")) ||
			(eql=skip("==")) || (fle=skip("<=")) || skip(">=")) {
		genas("push eax");
		expr_add_sub();
		genas("mov ebx eax");
		genas("pop eax");
		gencode(0x39); gencode(0xd8); // cmp %eax, %ebx
		/*
		 * < setl 0x9c
		 * > setg 0x9f
		 * <= setle 0x9e
		 * >= setge 0x9d
		 * == sete 0x94
		 * != setne 0x95
		 */
		gencode(0x0f); gencode(lt ? 0x9c : gt ? 0x9f : ne ? 0x95 : eql ? 0x94 : fle ? 0x9e : 0x9d); gencode(0xc0); // setX al
		gencode(0x0f); gencode(0xb6); gencode(0xc0); // movzx eax al
	}

	return 0;
}

int expr_add_sub() {
	int add;
	expr_mul_div();
	while((add = skip("+")) || skip("-")) {
		genas("push eax");
		expr_mul_div();
		genas("mov ebx eax");  // mov %ebx %eax
		genas("pop eax");
		if(add) { genas("add eax ebx"); }// add %eax %ebx
		else { genas("sub eax ebx"); } // sub %eax %ebx
	}
	return 0;
}

int expr_mul_div() {
	int mul, div;
	expr_primary();
	while((mul = skip("*")) || (div=skip("/")) || skip("%")) {
		genas("push eax");
		expr_primary();
		genas("mov ebx eax"); // mov %ebx %eax
		genas("pop eax");
		if(mul) {
			genas("mul ebx");
		} else if(div) {
			genas("mov edx 0");
			genas("div ebx");
		} else { //mod
			genas("mov edx 0");
			genas("div ebx");
			genas("mov eax edx");
		}
	}
	return 0;
}

int expr_primary() {
	int is_get_addr = 0, ispare = 0;

	if(skip("&")) is_get_addr = 1;

	if(is_number_tok()) { // number?
		genas("mov eax %d", atoi(tok.tok[tok.pos++].val));
	} else if(skip("'")) { // char?
		genas("mov eax %d", tok.tok[tok.pos++].val[0]);
		skip("'");
	} else if(is_string_tok()) { // string?
		gencode(0xb8); get_string();
		gencode_int32(0x00); // mov eax string_address
	} else if(is_ident_tok()) { // variable or inc or dec
		char *name = tok.tok[tok.pos].val, *mod_name = "";
		Variable *v; 

		if(streql(tok.tok[tok.pos + 1].val, ".")) { // module?
			mod_name = tok.tok[tok.pos++].val; 
			skip(".");
			name = tok.tok[tok.pos].val; 
		}

		if(is_asgmt()) {
			asgmt();
		} else {
			SKIP_TOK;
			if(skip("[")) { // Array?
				v = get_var(name , mod_name);
				if(v == NULL) v = get_var(name, module);
				if(v == NULL)
					error("error: %d: '%s' was not declare", tok.tok[tok.pos].nline, name);
				expr_entry();
				genas("mov ecx eax");

				if(v->loctype == V_LOCAL) {
					gencode(0x8b); gencode(0x55); gencode(256 - ADDR_SIZE * v->id); // mov edx, [ebp - v*4]
				} else if(v->loctype == V_GLOBAL) {
					gencode(0x8b); gencode(0x15); gencode_int32(v->id); // mov edx, GLOBAL_ADDR
				}

				if(v->type == T_INT) {
					gencode(0x8b); gencode(0x04); gencode(0x8a);// mov eax, [edx + ecx * 4]
				} else {
					gencode(0x0f); gencode(0xb6); gencode(0x04); gencode(0x0a);// movzx eax, [edx + ecx]
				}

				if(!skip("]"))
					error("error: %d: expected expression ']'", tok.tok[tok.pos].nline);
			} else if((ispare = skip("(")) || is_stdfunc(name, mod_name) || get_func(name, mod_name)) { // Function?
				int is_stdfunc = make_stdfunc(name, mod_name);

				if(is_lib_module(mod_name)) { // library function
					size_t params = 0;
					if(is_number_tok() || is_ident_tok() || 
							is_string_tok() || streql(tok.tok[tok.pos].val, "(")) { // has arg?
						for(int i = tok.pos; !streql(tok.tok[i].val, ")"); i++) 
							params += streql(tok.tok[i].val, ","); // count params
						params++;
						for(int i = 0; i < params; i++) {
							expr_entry();
							gencode(0x89); gencode(0x44); gencode(0x24); gencode(i * ADDR_SIZE);
							if(i < params - 1 && !skip(","))
								error("error: %d: expected ','", tok.tok[tok.pos].nline);
						} 
					}
					gencode(0xe8); gencode_int32(call_lib_func(name, mod_name) - (uint32_t)&ntvCode[ntvCount] - 4); // call func
				} else if(!is_stdfunc) {	// user function
{'fraction_non_alphanumeric': 0.22285777142228577, 'fraction_numerical': 0.02969970300296997, 'mean_word_length': 3.2826189354686766, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6127451', 'n_tokens_mistral': 4503, 'n_tokens_neox': 3901, 'n_words': 794}