intercodes translate_VarDec(struct Node *node,operand *place) {
	intercodes code1,code2,code3,code4;
	struct Node *child = node->child;
	assert(child != NULL);
	//ID
	if (strcmp(child->type,"ID") == 0) {
		int id = getVarID(child);
		enum varType type;
		union varp vp = getVar(child,&type);
		operand v1 = new_var(id);
		if (place != NULL) {
			*place = v1;
		}
		if (type == varInt || type == varFloat) { 
			return NULL;
		}
		else if (type == varArray || type == varStruct) {
			int size = get_structure_size(vp,type);
			operand c1 = new_constant(size);
			code1 = gen_assign(DEC_K,v1,c1);
			return code1;
		}
		else {
			printf("type is varError%d\n",type == varError);
			exit(-1);
		}
	}
	//VarDec INT LB INT RB
	return translate_VarDec(child,NULL);
}
Beispiel #2
0
void stmt_list_parse(node* list) {
	while(list) {
		if(list && list->type == LIST_NODE) {
			node* n = list->u.list.start;
			if(n->type == ASSIGN_NODE) {
				//printf("generating assignment quad in BB %s\n", currentBlock->name);
				gen_assign(n);
			} else if(n->type == BINOP_NODE) {
				gen_rvalue(n, NULL);
			} else if(n->type == UNOP_NODE) {
				gen_rvalue(n, NULL);
			} else if(n->type == IF_NODE || n->type == IFELSE_NODE) {
				gen_if(n);
			} else if(n->type == FOR_NODE) {
				gen_for(n);
			} else if(n->type == WHILE_NODE) {
				gen_while(n);
			} else if(n->type == JUMP_NODE) {
				gen_jmp(n);
			} else if(n->type == CALL_NODE) { //Function Call
				int argnum = n->u.call.argnum;
				qnode* num = qnode_new(Q_CONSTANT);
				num->name = malloc(100);
				sprintf(num->name, "%i", argnum);
				num->u.value = argnum;
				emit(O_ARGNUM, NULL, num, NULL);
				if(argnum) { //Generate argument quad
					node* argptr = n->u.call.args;
					while(argptr) {
						emit(O_ARGDEF, NULL, gen_rvalue(argptr->u.list.start, NULL), NULL);
						if(argptr->next) {
							argptr = argptr->next;
						} else {
							break;
						}
					}
				}
				emit(O_CALL, NULL, gen_rvalue(n->u.call.function, NULL), NULL);
			} else if(n->type == IDENT_NODE || n->type == DEFAULT_NODE) {
				//do nothing
			} else {
				fprintf(stderr, "QUAD ERROR: Unrecognized Node Type %i\n", n->type);
				exit(1);
			}
			if(list->next) {
				list = list->next;
			} else {
				break;
			}
		} else {
			fprintf(stderr, "QUAD ERROR: Invalid Statement List\n");
			break;
		}
	}
}
intercodes translate_Dec(struct Node *node) {
	struct Node *child = node->child;
	assert(child != NULL);
	intercodes code1,code2,code3;
	//VarDec
	if (child->sibling == NULL) { 
		return translate_VarDec(child,NULL);
	}
	//VarDec ASSIGNOP Exp
	if (child->sibling != NULL && strcmp(child->sibling->type,"ASSIGNOP") == 0) {
		operand t1 = NULL;
		code1 = translate_VarDec(child,&t1);
		operand t2 = new_tmp();
		code2 = translate_Exp(child->sibling->sibling,t2);
		code3 = gen_assign(ASSIGN_K,t1,t2);
		code1 = link(code1,code2);
		code1 = link(code1,code3);
		return code1;
	}
}
Beispiel #4
0
LLVMValueRef gen_expr(compile_t* c, ast_t* ast)
{
  LLVMValueRef ret;
  bool has_scope = ast_has_scope(ast);
  bool has_source = codegen_hassource(c);

  if(has_scope)
  {
    codegen_pushscope(c);

    // Dwarf a new lexical scope, if necessary.
    if(has_source)
      dwarf_lexicalscope(&c->dwarf, ast);
  }

  switch(ast_id(ast))
  {
    case TK_SEQ:
      ret = gen_seq(c, ast);
      break;

    case TK_FVARREF:
    case TK_FLETREF:
      ret = gen_fieldload(c, ast);
      break;

    case TK_PARAMREF:
      ret = gen_param(c, ast);
      break;

    case TK_VAR:
    case TK_LET:
      ret = gen_localdecl(c, ast);
      break;

    case TK_VARREF:
    case TK_LETREF:
      ret = gen_localload(c, ast);
      break;

    case TK_IF:
      ret = gen_if(c, ast);
      break;

    case TK_WHILE:
      ret = gen_while(c, ast);
      break;

    case TK_REPEAT:
      ret = gen_repeat(c, ast);
      break;

    case TK_TRY:
    case TK_TRY_NO_CHECK:
      ret = gen_try(c, ast);
      break;

    case TK_MATCH:
      ret = gen_match(c, ast);
      break;

    case TK_CALL:
      ret = gen_call(c, ast);
      break;

    case TK_CONSUME:
      ret = gen_expr(c, ast_childidx(ast, 1));
      break;

    case TK_RECOVER:
      ret = gen_expr(c, ast_childidx(ast, 1));
      break;

    case TK_BREAK:
      ret = gen_break(c, ast);
      break;

    case TK_CONTINUE:
      ret = gen_continue(c, ast);
      break;

    case TK_RETURN:
      ret = gen_return(c, ast);
      break;

    case TK_ERROR:
      ret = gen_error(c, ast);
      break;

    case TK_IS:
      ret = gen_is(c, ast);
      break;

    case TK_ISNT:
      ret = gen_isnt(c, ast);
      break;

    case TK_ASSIGN:
      ret = gen_assign(c, ast);
      break;

    case TK_THIS:
      ret = gen_this(c, ast);
      break;

    case TK_TRUE:
      ret = LLVMConstInt(c->i1, 1, false);
      break;

    case TK_FALSE:
      ret = LLVMConstInt(c->i1, 0, false);
      break;

    case TK_INT:
      ret = gen_int(c, ast);
      break;

    case TK_FLOAT:
      ret = gen_float(c, ast);
      break;

    case TK_STRING:
      ret = gen_string(c, ast);
      break;

    case TK_TUPLE:
      ret = gen_tuple(c, ast);
      break;

    case TK_FFICALL:
      ret = gen_ffi(c, ast);
      break;

    case TK_AMP:
      ret = gen_addressof(c, ast);
      break;

    case TK_IDENTITY:
      ret = gen_identity(c, ast);
      break;

    case TK_DONTCARE:
      ret = GEN_NOVALUE;
      break;

    case TK_COMPILER_INTRINSIC:
      ast_error(ast, "unimplemented compiler intrinsic");
      LLVMBuildUnreachable(c->builder);
      ret = GEN_NOVALUE;
      break;

    default:
      ast_error(ast, "not implemented (codegen unknown)");
      return NULL;
  }

  if(has_scope)
  {
    codegen_popscope(c);

    if(has_source)
      dwarf_finish(&c->dwarf);
  }

  return ret;
}
Beispiel #5
0
LLVMValueRef gen_expr(compile_t* c, ast_t* ast)
{
  LLVMValueRef ret;
  bool has_scope = ast_has_scope(ast);

  if(has_scope)
    codegen_pushscope(c, ast);

  switch(ast_id(ast))
  {
    case TK_SEQ:
      ret = gen_seq(c, ast);
      break;

    case TK_FVARREF:
    case TK_FLETREF:
      ret = gen_fieldload(c, ast);
      break;

    case TK_EMBEDREF:
      ret = gen_fieldptr(c, ast);
      break;

    case TK_PARAMREF:
      ret = gen_param(c, ast);
      break;

    case TK_VAR:
    case TK_LET:
    case TK_MATCH_CAPTURE:
      ret = gen_localdecl(c, ast);
      break;

    case TK_VARREF:
    case TK_LETREF:
      ret = gen_localload(c, ast);
      break;

    case TK_IF:
      ret = gen_if(c, ast);
      break;

    case TK_WHILE:
      ret = gen_while(c, ast);
      break;

    case TK_REPEAT:
      ret = gen_repeat(c, ast);
      break;

    case TK_TRY:
    case TK_TRY_NO_CHECK:
      ret = gen_try(c, ast);
      break;

    case TK_MATCH:
      ret = gen_match(c, ast);
      break;

    case TK_CALL:
      ret = gen_call(c, ast);
      break;

    case TK_CONSUME:
      ret = gen_expr(c, ast_childidx(ast, 1));
      break;

    case TK_RECOVER:
      ret = gen_expr(c, ast_childidx(ast, 1));
      break;

    case TK_BREAK:
      ret = gen_break(c, ast);
      break;

    case TK_CONTINUE:
      ret = gen_continue(c, ast);
      break;

    case TK_RETURN:
      ret = gen_return(c, ast);
      break;

    case TK_ERROR:
      ret = gen_error(c, ast);
      break;

    case TK_IS:
      ret = gen_is(c, ast);
      break;

    case TK_ISNT:
      ret = gen_isnt(c, ast);
      break;

    case TK_ASSIGN:
      ret = gen_assign(c, ast);
      break;

    case TK_THIS:
      ret = gen_this(c, ast);
      break;

    case TK_TRUE:
      ret = LLVMConstInt(c->i1, 1, false);
      break;

    case TK_FALSE:
      ret = LLVMConstInt(c->i1, 0, false);
      break;

    case TK_INT:
      ret = gen_int(c, ast);
      break;

    case TK_FLOAT:
      ret = gen_float(c, ast);
      break;

    case TK_STRING:
      ret = gen_string(c, ast);
      break;

    case TK_TUPLE:
      ret = gen_tuple(c, ast);
      break;

    case TK_FFICALL:
      ret = gen_ffi(c, ast);
      break;

    case TK_ADDRESS:
      ret = gen_addressof(c, ast);
      break;

    case TK_DIGESTOF:
      ret = gen_digestof(c, ast);
      break;

    case TK_DONTCARE:
      ret = GEN_NOVALUE;
      break;

    case TK_COMPILE_INTRINSIC:
      ast_error(c->opt->check.errors, ast, "unimplemented compile intrinsic");
      return NULL;

    case TK_COMPILE_ERROR:
    {
      ast_t* reason_seq = ast_child(ast);
      ast_t* reason = ast_child(reason_seq);
      ast_error(c->opt->check.errors, ast, "compile error: %s",
        ast_name(reason));
      return NULL;
    }

    default:
      ast_error(c->opt->check.errors, ast, "not implemented (codegen unknown)");
      return NULL;
  }

  if(has_scope)
    codegen_popscope(c);

  return ret;
}
//translate
intercodes translate_Exp(struct Node *node, operand place) {
	struct Node *child = node->child;
	assert(child != NULL);
	intercodes code1 = NULL;
	intercodes code2 = NULL;
	intercodes code3 = NULL;
	intercodes code4 = NULL;
	intercodes code5 = NULL;
	//INT
	if (strcmp(child->type,"INT") == 0) {
		operand c1 = new_constant(atoi(child->text));
		code1 = gen_assign(ASSIGN_K,place,c1);
		return code1;
	}
	//ID
	if (strcmp(child->type,"ID") == 0 && child->sibling == NULL) {
		int id = getVarID(child);
		operand v1 = new_var(id);
		code1 = gen_assign(ASSIGN_K,place,v1);
		return code1;
	}
	//Exp1 ASSINGOP Exp2
	if (strcmp(child->type,"Exp") == 0 && strcmp(child->sibling->type,"ASSIGNOP") == 0) {
		//Exp1 is ID (ID = Exp2)
//		printf("%s\n",child->child->type);
		if (strcmp(child->child->type,"ID") == 0) {
			operand t1 =  new_tmp();
			int id = getVarID(child->child);
			operand v1 = new_var(id);
			code1 = translate_Exp(child->sibling->sibling,t1);
			code2 = gen_assign(ASSIGN_K,v1,t1);
		//	code1 = link(code1,code2);
			if (place != NULL) {
				code3 = gen_assign(ASSIGN_K,place,v1);
				code1 = link(code1,code3);
			}
			return code1;
		}
		//Exp[Exp] = Exp2
	}
	//Exp1 PLUS/MINUS/STAR/DIV Exp2
	if (strcmp(child->type,"Exp") == 0 &&
		(strcmp(child->sibling->type,"PLUS") == 0 
		|| strcmp(child->sibling->type,"MINUS") == 0
		|| strcmp(child->sibling->type,"STAR") == 0
		|| strcmp(child->sibling->type,"DIV") == 0)) {
		operand t1 = new_tmp();
		operand t2 = new_tmp();
		code1 = translate_Exp(child,t1);
		code2 = translate_Exp(child->sibling->sibling,t2);
		//printf("%d %d\n", t1->u.tmp_no, t2 -> u.tmp_no);
		if (strcmp(child->sibling->type,"PLUS") == 0) {
			code3 = gen_binop(ADD_K,place,t1,t2);
		}
		else if (strcmp(child->sibling->type,"MINUS") == 0)
			code3 = gen_binop(SUB_K,place,t1,t2);
		else if (strcmp(child->sibling->type,"STAR") == 0)
			code3 = gen_binop(MUL_K,place,t1,t2);
		else if (strcmp(child->sibling->type,"DIV") == 0)
			code3 = gen_binop(DIV_K,place,t1,t2);
		//code1 = link(code1,code2);
		//code1 = link(code1,code3);
		return code1;
	}
	//MINUS Exp1
	if (strcmp(child->type,"MINUS") == 0)  {
		operand t1 = new_tmp();
		code1 = translate_Exp(child,t1);
		operand c1 = new_constant(0);
		code2 = gen_binop(SUB_K,place,c1,t1);
		code1 = link(code1,code2);
		return code1;
	}
	//Exp1 RELOP Exp2
	//NOT Exp1
	//Exp1 AND Exp2
	//Exp1 OR Exp2
	if (strcmp(child->type,"NOT") == 0 
	|| strcmp(child->sibling->type,"RELOP") == 0
	|| strcmp(child->sibling->type,"AND") == 0
	|| strcmp(child->sibling->type,"OR") == 0) {
		operand label1 = new_label();
		operand label2 = new_label();
		operand c1 = new_constant(0);
		operand c2 = new_constant(1);
		code1 = gen_assign(ASSIGN_K,place,c1);
		code2 = translate_Cond(node,label1,label2);
		code3 = gen_one(LABEL_K,label1);
		code4 = gen_assign(ASSIGN_K,place,c2);
		code5 = gen_one(LABEL_K,label2);
		code1 = link(code1,code2);
		code1 = link(code1,code3);
		code1 = link(code1,code4);
		code1 = link(code1,code5);
		return code1;
	}
	//ID LP RP
	if (strcmp(child->sibling->sibling->type,"LP") == 0 && strcmp(child->sibling->sibling->type,"RP") == 0) {
		char *func_name = child->text;
		if (strcmp(func_name,"read") == 0) {
			if (place == NULL) {
				operand t1 = new_tmp();
				code1 = gen_one(READ_K,t1);
			}
			else 
				code1 = gen_one(READ_K,place);
			return code1;
		}
		struct funMes *func_node = getFunMes(child);
		assert(func_node != NULL);
		operand f1 = new_function(func_name);
		if (place != NULL && place->kind != ADDRESS) 
			code1 = gen_assign(CALL_K,place,f1);
		else if (place != NULL && place->kind == ADDRESS) {
			operand t2 = new_tmp();
			code1 = gen_assign(CALL_K,t2,f1);
			code2 = gen_assign(ASSIGN_K,place,t2);
			code1 = link(code1,code2);
		}
		else {
			operand t2 = new_tmp();
			code1 = gen_assign(CALL_K,t2,f1);
		}
		return code1;
	}
	//ID LP Args RP
	if (strcmp(child->sibling->type,"LP") == 0 && strcmp(child->sibling->sibling->type,"Args") == 0) {
		char *func_name = child->text;
		operand *arg_list = (operand *)malloc(sizeof(operand) * 10);
		int arg_num = 0;
		code1 = translate_Args(child->sibling->sibling,arg_list,&arg_num);
		if (strcmp(func_name,"write") == 0) {
			assert(arg_num == 1);
			operand t1;
			if (arg_list[0]->kind == ADDRESS) {
				t1 = new_tmp();
				code2 = gen_assign(ASSIGN_K,t1,arg_list[0]);
				code1 = link(code1,code2);
			}
			else 
				t1 = arg_list[0];
			code3 = gen_one(WRITE_K,t1);
			code1 = link(code1,code3);
			return code1;
		}
		int i;
		for (i = 0;i < arg_num;i++) {
			code2 = gen_one(ARG_K,arg_list[i]);
			code1 = link(code1,code2);
		}
		operand f1 = new_function(func_name);
		if (place != NULL && place->kind != ADDRESS) 
			code3 = gen_assign(CALL_K,place,f1);
		else if (place != NULL && place->kind == ADDRESS) {
			operand t2 = new_tmp();
			code1 = gen_assign(CALL_K,t2,f1);
			code2 = gen_assign(ASSIGN_K,place,t2);
			code1 = link(code1,code2);
		}
		else {
			operand t2 = new_tmp();
			code3 = gen_assign(CALL_K,t2,f1);
		}
		code1 = link(code1,code3);
		return code1;
	}
	//LP Exp RP
	if (strcmp(child->type,"LP") == 0) {
		return translate_Exp(child->sibling,place);
	}
	//Exp1 LB Exp2 RB
	if (strcmp(child->type,"LB") == 0) {
		return translate_array(node,place,NULL,NULL);
	}
	//Exp DOT ID
	return NULL;

}