static void DumpVisitor_visitLetExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { DUMPER(self)->indent++; emit_string("LET ", "", "", DUMPER(self)->indent); DUMPER(self)->indent++; handleExpr(kctx, self, kExpr_at(expr, 1)); emit_string(":=", "", "", DUMPER(self)->indent); handleExpr(kctx, self, kExpr_at(expr, 2)); DUMPER(self)->indent--; DUMPER(self)->indent--; }
static void DumpVisitor_visitOrExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { unsigned i; emit_string("OR", "", "", DUMPER(self)->indent); DUMPER(self)->indent++; for (i = 1; i < kArray_size(expr->cons); ++i) { handleExpr(kctx, self, kExpr_at(expr, i)); } DUMPER(self)->indent--; }
static kbool_t kStmt_AddClassField(KonohaContext *kctx, kStmt *stmt, kGamma *gma, KonohaClassVar *definedClass, kshortflag_t flag, ktype_t ty, kExpr *expr) { if(Expr_isTerm(expr)) { // String name kString *name = expr->termToken->text; ksymbol_t symbol = ksymbolA(S_text(name), S_size(name), SYM_NEWID); KLIB KonohaClass_AddField(kctx, definedClass, flag, ty, symbol); return true; } else if(expr->syn->keyword == KW_LET) { // String name = "naruto"; kExpr *lexpr = kExpr_at(expr, 1); if(Expr_isTerm(lexpr)) { kString *name = lexpr->termToken->text; ksymbol_t symbol = ksymbolA(S_text(name), S_size(name), SYM_NEWID); kExpr *vexpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, ty, 0); if(vexpr == K_NULLEXPR) return false; if(vexpr->build == TEXPR_CONST) { KLIB KonohaClass_AddField(kctx, definedClass, flag, ty, symbol); KonohaClass_setClassFieldObjectValue(kctx, definedClass, symbol, vexpr->objectConstValue); } else if(vexpr->build == TEXPR_NCONST) { KLIB KonohaClass_AddField(kctx, definedClass, flag, ty, symbol); KonohaClass_setClassFieldUnboxValue(kctx, definedClass, symbol, vexpr->unboxConstValue); } else if(vexpr->build == TEXPR_NULL) { KLIB KonohaClass_AddField(kctx, definedClass, flag, ty, symbol); } else { SUGAR kStmt_Message2(kctx, stmt, lexpr->termToken, ErrTag, "field initial value must be const: %s", S_text(name)); return false; } return true; } } else if(expr->syn->keyword == KW_COMMA) { // String (firstName = naruto, lastName) size_t i; for(i = 1; i < kArray_size(expr->cons); i++) { if(!kStmt_AddClassField(kctx, stmt, gma, definedClass, flag, ty, kExpr_at(expr, i))) return false; } return true; } SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "field name is expected"); return false; }
static void AND_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx) { int i, size = kArray_size(expr->cons); kBasicBlock* lbTRUE = new_BasicBlockLABEL(kctx); kBasicBlock* lbFALSE = new_BasicBlockLABEL(kctx); for(i = 1; i < size; i++) { EXPR_asmJMPIF(kctx, stmt, a, kExpr_at(expr, i), 0/*FALSE*/, lbFALSE, shift, espidx); } ASM(NSET, NC_(a), 1/*O_data(K_TRUE)*/, CT_Boolean); ASM_JMP(kctx, lbTRUE); ASM_LABEL(kctx, lbFALSE); // false ASM(NSET, NC_(a), 0/*O_data(K_FALSE)*/, CT_Boolean); ASM_LABEL(kctx, lbTRUE); // TRUE }
static void LETEXPR_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx) { kExpr *leftHandExpr = kExpr_at(expr, 1); kExpr *rightHandExpr = kExpr_at(expr, 2); DBG_P("LET (%s) a=%d, shift=%d, espidx=%d", TY_t(expr->ty), a, shift, espidx); if(leftHandExpr->build == TEXPR_LOCAL) { EXPR_asm(kctx, stmt, leftHandExpr->index, rightHandExpr, shift, espidx); if(expr->ty != TY_void && a != leftHandExpr->index) { NMOV_asm(kctx, a, leftHandExpr->ty, leftHandExpr->index); } } else if(leftHandExpr->build == TEXPR_STACKTOP) { DBG_P("LET TEXPR_STACKTOP a=%d, leftHandExpr->index=%d, espidx=%d", a, leftHandExpr->index, espidx); EXPR_asm(kctx, stmt, leftHandExpr->index + shift, rightHandExpr, shift, espidx); if(expr->ty != TY_void && a != leftHandExpr->index + shift) { NMOV_asm(kctx, a, leftHandExpr->ty, leftHandExpr->index + shift); } } else{ assert(leftHandExpr->build == TEXPR_FIELD); EXPR_asm(kctx, stmt, espidx, rightHandExpr, shift, espidx); kshort_t index = (kshort_t)leftHandExpr->index; kshort_t xindex = (kshort_t)(leftHandExpr->index >> (sizeof(kshort_t)*8)); if(TY_isUnbox(rightHandExpr->ty)) { ASM(XNMOV, OC_(index), xindex, NC_(espidx), CT_(leftHandExpr->ty)); if(expr->ty != TY_void) { ASM(NMOVx, NC_(a), OC_(index), xindex, CT_(leftHandExpr->ty)); } } else { ASM(XNMOV, OC_(index), xindex, OC_(espidx), CT_(leftHandExpr->ty)); if(expr->ty != TY_void) { ASM(NMOVx, OC_(a), OC_(index), xindex, CT_(leftHandExpr->ty)); } } } }
static void DumpVisitor_visitCallExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { KGrowingBuffer wb; KLIB Kwb_init(&(kctx->stack->cwb), &wb); kMethod *mtd = CallExpr_getMethod(expr); KLIB Kwb_printf(kctx, &wb, "CALL: '%s%s'", T_mn(mtd->mn)); DUMPER(self)->indent++; emit_string(KLIB Kwb_top(kctx, &wb, 1), "(", "", DUMPER(self)->indent); DUMPER(self)->indent++; unsigned i; for (i = 1; i < kArray_size(expr->cons); ++i) { handleExpr(kctx, self, kExpr_at(expr, i)); } DUMPER(self)->indent--; emit_string(")", "", "", DUMPER(self)->indent); DUMPER(self)->indent--; KLIB Kwb_free(&wb); }
static void CALL_asm(KonohaContext *kctx, kStmt *stmt, int a, kExpr *expr, int shift, int espidx) { kMethod *mtd = expr->cons->methodItems[0]; DBG_ASSERT(IS_Method(mtd)); int i, s = Method_isStatic(mtd) ? 2 : 1, thisidx = espidx + K_CALLDELTA; #ifdef _CLASSICVM if (CLASSICVM_CALL_asm(kctx, mtd, expr, shift, espidx)) { return; } #endif for(i = s; i < kArray_size(expr->cons); i++) { kExpr *exprN = kExpr_at(expr, i); DBG_ASSERT(IS_Expr(exprN)); EXPR_asm(kctx, stmt, thisidx + i - 1, exprN, shift, thisidx + i - 1); } int argc = kArray_size(expr->cons) - 2; // if (mtd->mn == MN_new && mtd->invokeMethodFunc == MethodFunc_abstract) { // /* do nothing */ // } else // if(Method_isFinal(mtd) || !Method_isVirtual(mtd)) { // if(mtd->invokeMethodFunc != MethodFunc_runVirtualMachine) { // ASM(SCALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), mtd, KLIB Knull(kctx, CT_(expr->ty))); // } // else { // ASM(VCALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), mtd, KLIB Knull(kctx, CT_(expr->ty))); // } // } // else { if(Method_isFinal(mtd) || !Method_isVirtual(mtd)) { ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, CT_Method); } else { ASM(LOOKUP, SFP_(thisidx), Stmt_nameSpace(stmt), mtd); } ASM(CALL, ctxcode->uline, SFP_(thisidx), ESP_(espidx, argc), KLIB Knull(kctx, CT_(expr->ty))); }