static kbool_t class_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("$ClassName"), 0, NULL, 0, 0, PatternMatch_ClassName, NULL, NULL, NULL, NULL, }, { SYM_("class"), 0, "\"class\" $ClassName [\"extends\" extends: $Type] [$Block]", 0, 0, NULL, NULL, Statement_class, NULL, NULL, }, { SYM_("."), 0, NULL, -1, 0, NULL, NULL, NULL, NULL, TypeCheck_Getter, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t subtype_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("<:"), 0, NULL, Precedence_CStyleMUL, 0, NULL, NULL, NULL, NULL, TypeCheck_InstanceOf, }, { SYM_("as"), 0, NULL, Precedence_CStyleMUL, 0, NULL, NULL, NULL, NULL, TypeCheck_as}, { SYM_("to"), 0, NULL, Precedence_CStyleMUL, 0, NULL, NULL, NULL, NULL, TypeCheck_to}, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static KMETHOD Statement_class(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); kToken *tokenClassName = SUGAR kStmt_GetToken(kctx, stmt, SYM_("$ClassName"), NULL); kNameSpace *ns = Stmt_ns(stmt); int isNewlyDefinedClass = false; KonohaClassVar *definedClass = (KonohaClassVar *)KLIB kNameSpace_GetClassByFullName(kctx, ns, S_text(tokenClassName->text), S_size(tokenClassName->text), NULL); if(definedClass == NULL) { // Already defined kshortflag_t cflag = kStmt_ParseClassFlag(kctx, stmt, kClass_Virtual); KMakeTraceUL(trace, sfp, stmt->uline); definedClass = kNameSpace_DefineClassName(kctx, ns, cflag, tokenClassName->text, trace); isNewlyDefinedClass = true; } kBlock *bk = kStmt_ParseClassBlockNULL(kctx, stmt, tokenClassName); size_t declsize = kBlock_countFieldSize(kctx, bk); if(isNewlyDefinedClass) { // Already defined KonohaClass *superClass = CT_Object; kToken *tokenSuperClass= SUGAR kStmt_GetToken(kctx, stmt, SYM_("extends"), NULL); if(tokenSuperClass != NULL) { DBG_ASSERT(Token_isVirtualTypeLiteral(tokenSuperClass)); superClass = CT_(Token_typeLiteral(tokenSuperClass)); if(CT_is(Final, superClass)) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s is final", CT_t(superClass)); KReturnUnboxValue(false); } if(CT_is(Virtual, superClass)) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s is still virtual", CT_t(superClass)); KReturnUnboxValue(false); } } size_t initsize = (bk != NULL) ? declsize : initFieldSizeOfVirtualClass(superClass); KonohaClass_InitField(kctx, definedClass, superClass, initsize); } else { if(declsize > 0 && !CT_is(Virtual, definedClass)) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s has already defined", CT_t(definedClass)); KReturnUnboxValue(false); } } if(bk != NULL) { if(!kBlock_declClassField(kctx, bk, gma, definedClass)) { KReturnUnboxValue(false); } CT_set(Virtual, definedClass, false); } kToken_setTypeId(kctx, tokenClassName, ns, definedClass->typeId); kBlock_AddMethodDeclStmt(kctx, bk, tokenClassName, stmt); kStmt_done(kctx, stmt); KReturnUnboxValue(true); }
static kshortflag_t kStmt_ParseClassFlag(KonohaContext *kctx, kStmt *stmt, kshortflag_t cflag) { static KonohaFlagSymbolData ClassDeclFlag[] = { {kClass_Private}, {kClass_Singleton}, {kClass_Immutable}, {kClass_Prototype}, {kClass_Interface}, }; if(ClassDeclFlag[0].symbol == 0) { // this is a tricky technique ClassDeclFlag[0].symbol = SYM_("@Private"); ClassDeclFlag[1].symbol = SYM_("@Singleton"); ClassDeclFlag[2].symbol = SYM_("@Immutable"); ClassDeclFlag[3].symbol = SYM_("@Prototype"); ClassDeclFlag[4].symbol = SYM_("@Interface"); } return (kshortflag_t)SUGAR kStmt_ParseFlag(kctx, stmt, ClassDeclFlag, cflag); }
static void LoopStmt_asm(KonohaContext *kctx, kStmt *stmt, int shift, int espidx) { kBasicBlock* lbCONTINUE = new_BasicBlockLABEL(kctx); kBasicBlock* lbBREAK = new_BasicBlockLABEL(kctx); // BUILD_pushLABEL(kctx, stmt, lbCONTINUE, lbBREAK); KLIB kObject_setObject(kctx, stmt, SYM_("continue"), TY_BasicBlock, lbCONTINUE); KLIB kObject_setObject(kctx, stmt, SYM_("break"), TY_BasicBlock, lbBREAK); ASM_LABEL(kctx, lbCONTINUE); ASM_SAFEPOINT(kctx, espidx); EXPR_asmJMPIF(kctx, stmt, espidx, SUGAR kStmt_getExpr(kctx, stmt, KW_ExprPattern, NULL), 0/*FALSE*/, lbBREAK, shift, espidx); //BLOCK_asm(kctx, SUGAR kStmt_getBlock(kctx, stmt, KW_("iteration"), K_NULLBLOCK)); BLOCK_asm(kctx, SUGAR kStmt_getBlock(kctx, stmt, NULL/*DefaultNameSpace*/, KW_BlockPattern, K_NULLBLOCK), shift); ASM_JMP(kctx, lbCONTINUE); ASM_LABEL(kctx, lbBREAK); // BUILD_popLABEL(kctx); }
static kbool_t foreach_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("for"), 0, "\"for\" \"(\" [$Type] $Symbol \"in\" $Expr \")\" [$Block] ", 0, 0, NULL, NULL, NULL, Statement_for, NULL, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t defined_initPackage(KonohaContext *kctx, kNameSpace *ns, int argc, const char**args, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("defined"), 0, NULL, 0, Precedence_CStylePREUNARY, NULL, Expression_Defined, NULL, NULL, TypeCheck_Defined, }, { KW_END, }, }; SUGAR kNameSpace_defineSyntax(kctx, ns, SYNTAX); return true; }
static kbool_t float_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("$Float"), 0, NULL, 0, 0, NULL, NULL, NULL, NULL, TypeCheck_Float, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t defined_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("defined"), 0, NULL, 0, Precedence_CStylePREUNARY, NULL, Expression_Defined, NULL, NULL, TypeCheck_Defined, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t import_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("import"), 0, "\"import\" $Token $Token* [ \".*\"] ", 0, 0, NULL, NULL, Statement_import, NULL, NULL, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t const_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("const"), 0, "\"const\" $Symbol \"=\" $Expr", 0, 0, NULL, NULL, Statement_ConstDecl, NULL, NULL, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static KMETHOD Expression_BinarySugar(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(stmt, tokenList, beginIdx, operatorIdx, endIdx); kToken *opToken = tokenList->TokenItems[operatorIdx]; SugarSyntax *opSyntax = opToken->resolvedSyntaxInfo; if(opSyntax->macroParamSize == 2) { TokenSequence macro = {Stmt_nameSpace(stmt), tokenList}; TokenSequence_push(kctx, macro); MacroSet macroParam[] = { {SYM_("X"), tokenList, beginIdx, operatorIdx}, {SYM_("Y"), tokenList, operatorIdx+1, endIdx}, {0, NULL, 0, 0}, }; macro.TargetPolicy.RemovingIndent = true; SUGAR TokenSequence_applyMacro(kctx, ¯o, opSyntax->macroDataNULL_OnList, 0, kArray_size(opSyntax->macroDataNULL_OnList), opSyntax->macroParamSize, macroParam); kExpr *expr = SUGAR kStmt_parseExpr(kctx, stmt, macro.tokenList, macro.beginIdx, macro.endIdx, NULL); TokenSequence_pop(kctx, macro); KReturn(expr); } }
static KMETHOD Expression_Bracket(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(stmt, tokenList, beginIdx, operatorIdx, endIdx); KonohaClass *genericsClass = NULL; kNameSpace *ns = Stmt_ns(stmt); int nextIdx = SUGAR TokenUtils_ParseTypePattern(kctx, ns, tokenList, beginIdx, endIdx, &genericsClass); if(nextIdx != -1) { // to avoid Func[T] KReturn(SUGAR kStmt_ParseOperatorExpr(kctx, stmt, tokenList->TokenItems[beginIdx]->resolvedSyntaxInfo, tokenList, beginIdx, beginIdx, endIdx)); } kToken *currentToken = tokenList->TokenItems[operatorIdx]; if(beginIdx == operatorIdx) { /* transform '[ Value1, Value2, ... ]' to '(Call Untyped new (Value1, Value2, ...))' */ DBG_ASSERT(currentToken->resolvedSyntaxInfo->keyword == KW_BracketGroup); kExpr *arrayExpr = SUGAR new_UntypedCallStyleExpr(kctx, currentToken->resolvedSyntaxInfo, 2, currentToken, K_NULL); KReturn(SUGAR kStmt_AddExprParam(kctx, stmt, arrayExpr, currentToken->subTokenList, 0, kArray_size(currentToken->subTokenList), NULL)); } else { kExpr *leftExpr = SUGAR kStmt_ParseExpr(kctx, stmt, tokenList, beginIdx, operatorIdx, NULL); if(leftExpr == K_NULLEXPR) { KReturn(leftExpr); } if(leftExpr->syn->keyword == SYM_("new")) { // new int[100], new int[](); DBG_P("cur:%d, beg:%d, endIdx:%d", operatorIdx, beginIdx, endIdx); size_t subTokenSize = kArray_size(currentToken->subTokenList); if(subTokenSize == 0) { /* transform 'new Type0 [ ]' => (Call Type0 new) */ kExpr_Setsyn(leftExpr, SYN_(ns, KW_ExprMethodCall)); } else { /* transform 'new Type0 [ Type1 ] (...) => new 'Type0<Type1>' (...) */ KonohaClass *classT0 = NULL; kArray *subTokenList = currentToken->subTokenList; int beginIdx = -1; if(kArray_size(subTokenList) > 0) { beginIdx = SUGAR TokenUtils_ParseTypePattern(kctx, ns, subTokenList, 0, kArray_size(subTokenList), &classT0); } beginIdx = (beginIdx == -1) ? 0 : beginIdx; kExpr_Setsyn(leftExpr, SYN_(ns, KW_ExprMethodCall)); DBG_P("currentToken->subtoken:%d", kArray_size(subTokenList)); leftExpr = SUGAR kStmt_AddExprParam(kctx, stmt, leftExpr, subTokenList, beginIdx, kArray_size(subTokenList), "["); } } else { /* transform 'Value0 [ Value1 ]=> (Call Value0 get (Value1)) */ kTokenVar *tkN = /*G*/new_(TokenVar, 0, OnGcStack); tkN->resolvedSymbol= MN_toGETTER(0); tkN->uline = currentToken->uline; SugarSyntax *syn = SYN_(Stmt_ns(stmt), KW_ExprMethodCall); leftExpr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 2, tkN, leftExpr); leftExpr = SUGAR kStmt_AddExprParam(kctx, stmt, leftExpr, currentToken->subTokenList, 0, kArray_size(currentToken->subTokenList), "["); } KReturn(SUGAR kStmt_RightJoinExpr(kctx, stmt, leftExpr, tokenList, operatorIdx + 1, endIdx)); } }
static kbool_t RENAMEME_InitNameSpace(KonohaContext *kctx, kNameSpace *packageNS, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_INT_CONST IntData[] = { #define DEFINE_KEYWORD(KW) {#KW, TY_int, KW} DEFINE_KEYWORD(KW_ExprPattern), DEFINE_KEYWORD(KW_SymbolPattern), DEFINE_KEYWORD(KW_TextPattern), DEFINE_KEYWORD(KW_NumberPattern), DEFINE_KEYWORD(KW_TypePattern), DEFINE_KEYWORD(KW_ParenthesisGroup), DEFINE_KEYWORD(KW_BracketGroup), DEFINE_KEYWORD(KW_BraceGroup), DEFINE_KEYWORD(KW_BlockPattern), DEFINE_KEYWORD(KW_ParamPattern), DEFINE_KEYWORD(KW_TokenPattern), DEFINE_KEYWORD(TSTMT_UNDEFINED), DEFINE_KEYWORD(TSTMT_ERR), DEFINE_KEYWORD(TSTMT_EXPR), DEFINE_KEYWORD(TSTMT_BLOCK), DEFINE_KEYWORD(TSTMT_RETURN), DEFINE_KEYWORD(TSTMT_IF), DEFINE_KEYWORD(TSTMT_LOOP), DEFINE_KEYWORD(TSTMT_JUMP), DEFINE_KEYWORD(TEXPR_CONST), DEFINE_KEYWORD(TEXPR_NEW), DEFINE_KEYWORD(TEXPR_NULL), DEFINE_KEYWORD(TEXPR_NCONST), DEFINE_KEYWORD(TEXPR_LOCAL), DEFINE_KEYWORD(TEXPR_BLOCK), DEFINE_KEYWORD(TEXPR_FIELD), // DEFINE_KEYWORD(TEXPR_BOX), // DEFINE_KEYWORD(TEXPR_UNBOX), DEFINE_KEYWORD(TEXPR_CALL), DEFINE_KEYWORD(TEXPR_AND), DEFINE_KEYWORD(TEXPR_OR), DEFINE_KEYWORD(TEXPR_LET), DEFINE_KEYWORD(TEXPR_STACKTOP), DEFINE_KEYWORD(TypeCheckPolicy_NOCHECK), DEFINE_KEYWORD(TypeCheckPolicy_ALLOWVOID), DEFINE_KEYWORD(TypeCheckPolicy_COERCION), DEFINE_KEYWORD(TypeCheckPolicy_CONST), #undef DEFINE_KEYWORD {NULL}, }; KLIB kNameSpace_LoadConstData(kctx, ns, KonohaConst_(IntData), trace); KDEFINE_SYNTAX SYNTAX[] = { { SYM_("syntax"), 0, "\"syntax\" $Token*", 0, 0, NULL, NULL, Statement_syntax, NULL, NULL, }, { KW_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static void LoadNameSpaceMethodData(KonohaContext *kctx, kNameSpace *ns, int TY_symbol, KTraceInfo *trace) { int FN_keyword = SYM_("keyword"); int FN_func = SYM_("func"); /* Func[Int, Token, String] */ kparamtype_t P_FuncTokenize[] = {{TY_Token}, {TY_String}}; int TY_FuncToken = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_int, 2, P_FuncTokenize))->typeId; /* Func[Int, Stmt, Int, Token[], Int, Int] */ kparamtype_t P_FuncPatternMatch[] = {{TY_Stmt}, {TY_int}, {TY_TokenArray}, {TY_int}, {TY_int}}; int TY_FuncPatternMatch = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_int, 5, P_FuncPatternMatch))->typeId; /* Func[Expr, Stmt, Token[], Int, Int, Int] */ kparamtype_t P_FuncExpression[] = {{TY_Stmt}, {TY_TokenArray}, {TY_int}, {TY_int}, {TY_int}}; int TY_FuncExpression = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_Expr, 5, P_FuncExpression))->typeId; /* Func[Boolean, Stmt, Gamma] */ kparamtype_t P_FuncStatement[] = {{TY_Stmt}, {TY_Gamma}}; int TY_FuncStatement = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_boolean, 2, P_FuncStatement))->typeId; /* Func[Expr, Stmt, Expr, Gamma, Int] */ kparamtype_t P_FuncTypeCheck[] = {{TY_Stmt}, {TY_Expr}, {TY_Gamma}, {TY_int}}; int TY_FuncTypeCheck = (KLIB KonohaClass_Generics(kctx, CT_Func, TY_Expr, 4, P_FuncTypeCheck))->typeId; //DBG_P("func=%s", TY_t(TY_FuncTypeCheck)); KDEFINE_METHOD MethodData[] = { _Public|_Im, _F(NameSpace_DefinedSyntax), TY_boolean, TY_NameSpace, MN_("definedSyntax"), 1, TY_symbol, FN_keyword, _Public|_Im, _F(NameSpace_DefinedLiteral), TY_boolean, TY_NameSpace, MN_("definedLiteral"), 1, TY_symbol, FN_keyword, _Public|_Im, _F(NameSpace_DefinedStatement), TY_boolean, TY_NameSpace, MN_("definedStatement"), 1, TY_symbol, FN_keyword, _Public|_Im, _F(NameSpace_DefinedExpression), TY_boolean, TY_NameSpace, MN_("definedExpression"), 1, TY_symbol, FN_keyword, _Public|_Im, _F(NameSpace_DefinedBinaryOperator), TY_boolean, TY_NameSpace, MN_("definedBinaryOperator"), 1, TY_symbol, FN_keyword, // _Public, _F(NameSpace_compileAllDefinedMethods), TY_void, TY_NameSpace, MN_("compileAllDefinedMethods"), 0, _Public, _F(NameSpace_setTokenFunc), TY_void, TY_NameSpace, MN_("setTokenFunc"), 3, TY_symbol, FN_keyword, TY_int, FN_("kchar"), TY_FuncToken, FN_func, _Public, _F(NameSpace_AddPatternMatch), TY_void, TY_NameSpace, MN_("addPatternMatch"), 2, TY_symbol, FN_keyword, TY_FuncPatternMatch, FN_func, _Public, _F(NameSpace_AddExpression), TY_void, TY_NameSpace, MN_("addExpression"), 2, TY_symbol, FN_keyword, TY_FuncExpression, FN_func, _Public, _F(NameSpace_AddTopLevelStatement), TY_void, TY_NameSpace, MN_("addTopLevelStatement"), 2, TY_symbol, FN_keyword, TY_FuncStatement, FN_func, _Public, _F(NameSpace_AddStatement), TY_void, TY_NameSpace, MN_("addStatement"), 2, TY_symbol, FN_keyword, TY_FuncStatement, FN_func, _Public, _F(NameSpace_AddTypeCheck), TY_void, TY_NameSpace, MN_("addTypeCheck"), 2, TY_symbol, FN_keyword, TY_FuncTypeCheck, FN_func, DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); }
static kbool_t kNameSpace_InitGlobalObject(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { if(ns->globalObjectNULL_OnList == NULL) { KDEFINE_CLASS defGlobalObject = {0}; defGlobalObject.structname = "GlobalObject"; defGlobalObject.typeId = TY_newid; defGlobalObject.cflag = kClass_Singleton|kClass_Final; defGlobalObject.cstruct_size = sizeof(kGlobalObject); KonohaClass *cGlobalObject = KLIB kNameSpace_DefineClass(kctx, ns, NULL, &defGlobalObject, trace); ((kNameSpaceVar *)ns)->globalObjectNULL_OnList = KLIB Knull(kctx, cGlobalObject); return KLIB kNameSpace_SetConstData(kctx, ns, SYM_("global"), cGlobalObject->typeId, (uintptr_t)ns->globalObjectNULL_OnList, true/*isOverride*/, trace); } return true; }
static void kBlock_AddMethodDeclStmt(KonohaContext *kctx, kBlock *bk, kToken *tokenClassName, kStmt *classStmt) { if(bk != NULL) { size_t i; for(i = 0; i < kArray_size(bk->StmtList); i++) { kStmt *stmt = bk->StmtList->StmtItems[i]; if(stmt->syn->keyword == KW_TypeDeclPattern) continue; if(stmt->syn->keyword == KW_MethodDeclPattern) { kStmt *lastStmt = classStmt; KLIB kObject_setObject(kctx, stmt, SYM_("ClassName"), TY_Token, tokenClassName); SUGAR kBlock_InsertAfter(kctx, lastStmt->parentBlockNULL, lastStmt, stmt); lastStmt = stmt; } else { SUGAR kStmt_Message2(kctx, stmt, NULL, WarnTag, "%s is not available within the class clause", PSYM_t(stmt->syn->keyword)); } } } }
static kbool_t assign_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { SYM_("+="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("-="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("*="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("/="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("%="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("|="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("&="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_("<<="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { SYM_(">>="), (SYNFLAG_ExprLeftJoinOp2), NULL, Precedence_CStyleASSIGN, 0, NULL, Expression_BinarySugar, NULL, NULL, NULL, }, { KW_END, }, }; SUGAR kNameSpace_defineSyntax(kctx, ns, SYNTAX); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("+="), 2, "X Y X = (X) + (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("-="), 2, "X Y X = (X) - (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("*="), 2, "X Y X = (X) * (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("/="), 2, "X Y X = (X) / (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("%="), 2, "X Y X = (X) % (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("|="), 2, "X Y X = (X) | (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("&="), 2, "X Y X = (X) & (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_("<<="), 2, "X Y X = (X) << (Y)"); SUGAR kNameSpace_setMacroData(kctx, ns, SYM_(">>="), 2, "X Y X = (X) >> (Y)"); return true; }
return tok_start + ts - start - 1; } static KMETHOD ExprTyCheck_Float(KonohaContext *kctx, KonohaStack *sfp) { VAR_ExprTyCheck(stmt, expr, gma, reqty); kToken *tk = expr->termToken; sfp[4].floatValue = strtod(S_text(tk->text), NULL); // just using tramsformation float RETURN_(SUGAR kExpr_setUnboxConstValue(kctx, expr, TY_Float, sfp[4].unboxValue)); } static kbool_t float_initNameSpace(KonohaContext *kctx, kNameSpace *ns, kfileline_t pline) { KDEFINE_SYNTAX SYNTAX[] = { { .keyword = SYM_("float"), .type = TY_Float, }, { .keyword = SYM_("double"), .type = TY_Float, }, { .keyword = SYM_("$Float"), ExprTyCheck_(Float), }, { .keyword = KW_END, }, }; SUGAR kNameSpace_defineSyntax(kctx, ns, SYNTAX); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '0', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '1', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '2', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '3', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '4', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '5', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '6', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '7', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '8', parseNumber, NULL, 0); SUGAR kNameSpace_setTokenizeFunc(kctx, ns, '9', parseNumber, NULL, 0); return true;
static KMETHOD Statement_import(KonohaContext *kctx, KonohaStack *sfp) { int ret = false; VAR_Statement(stmt, gma); kTokenArray *tokenList = (kTokenArray *) kStmt_GetObjectNULL(kctx, stmt, KW_TokenPattern); if(tokenList == NULL) { KReturnUnboxValue(false); } kNameSpace *ns = Stmt_ns(stmt); SugarSyntaxVar *syn = (SugarSyntaxVar *) SYN_(ns, KW_ExprMethodCall); kExpr *expr; kTokenVar *tkImport = /*G*/new_(TokenVar, 0, OnGcStack); tkImport->resolvedSymbol = MN_("import"); if(IS_Token(tokenList)) { kTokenArray *list = ((kToken *) tokenList)->subTokenList; if(IS_String(list)) { /* case: import cstyle; */ kString *pkgname = (kString *) list; expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname); } else if(kArray_size(list) == 1) { /* case : import("konoha.import"); */ kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text); expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 3, tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0); } else if(kArray_size(list) == 2) { /* case : import("konoha.import", "import"); */ kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text); kExpr *param1 = makeStringConstValue(kctx, list->TokenItems[1]->text); expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 4, tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0, param1); } else { KReturnUnboxValue(false); } } else { KGrowingBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); /* case : import konoha.import */ ksymbol_t star = SYM_("*"); size_t i = 0; if(i + 2 < kArray_size(tokenList)) { for (; i < kArray_size(tokenList)-1; i+=2) { /* name . */ kToken *tk = tokenList->TokenItems[i+0]; if(i+2 < kArray_size(tokenList)) { kToken *startTk = tokenList->TokenItems[i+2]; if(startTk->resolvedSyntaxInfo->keyword == star) { break; } } KLIB KBuffer_Write(kctx, &wb, S_text(tk->text), S_size(tk->text)); KLIB KBuffer_Write(kctx, &wb, ".", 1); } } kString *name = tokenList->TokenItems[i]->text; KLIB KBuffer_Write(kctx, &wb, S_text(name), S_size(name)); kString *pkgname = KLIB new_kString(kctx, OnGcStack, KLIB KBuffer_Stringfy(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname); } KLIB kObjectProto_SetObject(kctx, stmt, KW_ExprPattern, TY_Expr, expr); ret = SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, CT_void, TypeCheckPolicy_ALLOWVOID); if(ret) { kStmt_typed(stmt, EXPR); } KReturnUnboxValue(ret); }
static kbool_t regexp_defineMethod(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { kregexpshare_t *base = (kregexpshare_t *)KCalloc_UNTRACE(sizeof(kregexpshare_t), 1); base->h.name = "regexp"; base->h.setup = kregexpshare_setup; base->h.reftrace = kregexpshare_reftrace; base->h.free = kregexpshare_free; KLIB KonohaRuntime_setModule(kctx, MOD_REGEXP, &base->h, trace); KDEFINE_CLASS RegExpDef = { STRUCTNAME(RegExp), .cflag = 0, .init = RegExp_init, .free = RegExp_free, .p = RegExp_p, }; base->cRegExp = KLIB kNameSpace_defineClass(kctx, ns, NULL, &RegExpDef, trace); ktype_t TY_StringArray0 = CT_StringArray0->typeId; KDEFINE_METHOD MethodData[] = { /*JS*/_Public|_Const|_Im, _F(RegExp_getglobal), TY_boolean, TY_RegExp, MN_("getglobal"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getignoreCase), TY_boolean, TY_RegExp, MN_("getignoreCase"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getmultiline), TY_boolean, TY_RegExp, MN_("getmultiline"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getsource), TY_String, TY_RegExp, MN_("getsource"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getlastIndex), TY_int, TY_RegExp, MN_("getlastIndex"), 0, /*JS*/_Public|_Im, _F(String_match), TY_StringArray0, TY_String, MN_("match"), 1, TY_RegExp, FN_("regexp"), /*JS*/_Public|_Const|_Im, _F(String_replace), TY_String, TY_String, MN_("replace"), 2, TY_RegExp, FN_("searchvalue"), TY_String, FN_("newvalue"), /*JS*/_Public|_Const|_Im, _F(String_search), TY_int, TY_String, MN_("search"), 1, TY_RegExp, FN_("searchvalue"), /*JS*/_Public|_Im, _F(String_split), TY_StringArray0, TY_String, MN_("split"), 1, TY_RegExp, FN_("separator"), /*JS*/_Public|_Im, _F(String_splitWithLimit), TY_StringArray0, TY_String, MN_("split"), 2, TY_RegExp, FN_("separator"), TY_int, FN_("limit"), /*JS*/_Public|_Const, _F(RegExp_new), TY_RegExp, TY_RegExp, MN_("new"), 1, TY_String, FN_("pattern"), /*JS*/_Public|_Const, _F(RegExp_new2), TY_RegExp, TY_RegExp, MN_("new"), 2, TY_String, FN_("pattern"), TY_String, FN_("option"), /*JS*/_Public|_Const, _F(RegExp_exec), TY_StringArray0, TY_RegExp, MN_("exec"), 1, TY_String, FN_("str"), /*JS*/_Public|_Const|_Im, _F(RegExp_test), TY_boolean, TY_RegExp, MN_("test"), 1, TY_String, FN_("str"), DEND, }; KLIB kNameSpace_loadMethodData(kctx, ns, MethodData); return true; } static KMETHOD TokenFunc_JavaScriptRegExp(KonohaContext *kctx, KonohaStack *sfp) { kTokenVar *tk = (kTokenVar *)sfp[1].asObject; int ch, prev = '/', pos = 1; const char *source = S_text(sfp[2].asString); if(source[pos] == '*' || source[pos] == '/') { KReturnUnboxValue(0); } /*FIXME: we need to care about context sensitive case*/ //int tokenListize = kArray_size(tenv->tokenList); //if(tokenListize > 0) { // kToken *tkPrev = tenv->tokenList->TokenItems[tokenListize - 1]; // if(tkPrev->unresolvedTokenType == TokenType_INT || // (tkPrev->topCharHint != '(' && tkPrev->unresolvedTokenType == TokenType_SYMBOL)) { // KReturnUnboxValue(0); // } //} while((ch = source[pos++]) != 0) { if(ch == '\n') { break; } if(ch == '/' && prev != '\\') { int pos0 = pos; while(isalpha(source[pos])) pos++; if(IS_NOTNULL(tk)) { kArray *a = (kArray *)KLIB new_kObject(kctx, OnField, CT_StringArray0, 2); // FIXME KFieldSet(tk, tk->subTokenList, a); KLIB new_kString(kctx, a, source + 1, (pos0-2), 0); KLIB new_kString(kctx, a, source + pos0, pos-pos0, 0); tk->unresolvedTokenType = SYM_("$RegExp"); } KReturnUnboxValue(pos); } prev = ch; } if(IS_NOTNULL(tk)) { SUGAR kToken_printMessage(kctx, tk, ErrTag, "must close with %s", "/"); } KReturnUnboxValue(pos-1); }