static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, LLVMValueRef r_value) { switch(ast_id(left)) { case TK_VAR: case TK_LET: { // Generate the locals. if(gen_localdecl(c, left) == NULL) return NULL; return assign_rvalue(c, ast_child(left), r_type, r_value); } case TK_FVARREF: case TK_FLETREF: { // The result is the previous value of the field. LLVMValueRef l_value = gen_fieldptr(c, left); return assign_one(c, l_value, r_value, r_type); } case TK_VARREF: { // The result is the previous value of the local. LLVMValueRef l_value = gen_localptr(c, left); return assign_one(c, l_value, r_value, r_type); } case TK_TUPLE: { // If the l_value is a tuple, assemble it as the result. LLVMValueRef result = gen_expr(c, left); if(result == NULL) return NULL; if(!assign_tuple(c, left, r_type, r_value)) return NULL; // Return the original tuple. return result; } case TK_ID: { // We may have recursed here from a VAR or LET or arrived directly. const char* name = ast_name(left); LLVMValueRef l_value = codegen_getlocal(c, name); return assign_one(c, l_value, r_value, r_type); } default: {} } assert(0); return NULL; }
static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, LLVMValueRef r_value) { switch(ast_id(left)) { case TK_SEQ: // The actual expression is inside a sequence node. while(ast_id(left) == TK_SEQ) { assert(ast_childcount(left) == 1); left = ast_child(left); } return assign_rvalue(c, left, r_type, r_value); case TK_VAR: case TK_LET: { // Generate the locals. if(gen_localdecl(c, left) == NULL) return NULL; return assign_rvalue(c, ast_child(left), r_type, r_value); } case TK_FVARREF: case TK_FLETREF: { // The result is the previous value of the field. LLVMValueRef l_value = gen_fieldptr(c, left); return assign_one(c, l_value, r_value, r_type); } case TK_EMBEDREF: { // Do nothing. The embed field was already passed as the receiver. return GEN_NOVALUE; } case TK_VARREF: { // The result is the previous value of the local. LLVMValueRef l_value = gen_localptr(c, left); return assign_one(c, l_value, r_value, r_type); } case TK_TUPLE: { // If the l_value is a tuple, assemble it as the result. LLVMValueRef result = gen_expr(c, left); if(result == NULL) return NULL; if(!assign_tuple(c, left, r_type, r_value)) return NULL; // Return the original tuple. return result; } case TK_ID: { // We may have recursed here from a VAR or LET or arrived directly. const char* name = ast_name(left); LLVMValueRef l_value = codegen_getlocal(c, name); return assign_one(c, l_value, r_value, r_type); } default: {} } assert(0); return NULL; }