static kbool_t namespace_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("namespace"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_namespace}}, { KSymbol_("const"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_ConstDecl}}, { KSymbol_("defined"), SYNFLAG_CFunc,0, Precedence_CStylePrefixOperator, {SUGARFUNC Expression_Defined}, {SUGARFUNC TypeCheck_Defined},}, { KSymbol_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("namespace")), "\"namespace\" $Expr", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("const")), "\"const\" $Symbol = $Expr", 0, trace); return true; }
static kbool_t cstyle_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("break"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_break}}, { KSymbol_("continue"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_continue}}, { KSymbol_("while"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_while} }, { KSymbol_("do"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_do} }, { KSymbol_END, }, /* sentinental */ }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("while")), "\"while\" \"(\" $Expr \")\" $Block", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("do")), "\"do\" $Block \"while\" \"(\" $Expr \")\"", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("break")), "\"break\"", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("continue")), "\"continue\"", 0, trace); return true; }
static kbool_t cstyle_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("$ForStmt"), SYNFLAG_CParseFunc, 0, 0, {SUGARFUNC PatternMatch_ForStmt}, }, { KSymbol_("for"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_CStyleFor} }, /* copied from CStyleWhile */ { KSymbol_("break"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_break}}, { KSymbol_("continue"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_continue}}, { KSymbol_END, }, /* sentinental */ }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("for")), "\"for\" \"(\" $ForStmt \")\" $Block", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("break")), "\"break\"", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("continue")), "\"continue\"", 0, trace); return true; }
static kbool_t class_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("$ClassName"), SYNFLAG_CFunc, 0, 0, {SUGARFUNC PatternMatch_ClassName}, {NULL}}, { KSymbol_("class"), SYNFLAG_CTypeFunc, 0, Precedence_Statement, {SUGAR patternParseFunc}, {SUGARFUNC Statement_class}}, { KSymbol_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("class")), "\"class\" $ClassName [\"extends\" extends: $Type] [$Block]", 0, trace); return true; }
static kbool_t StringInterpolation_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { #define PATTERN(X) KSymbol_##X##Pattern kSyntax *textSyntax = kSyntax_(KNULL(NameSpace), PATTERN(Text)); KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_TextPattern, SYNFLAG_CParseFunc, 0, 0, {SUGARFUNC Expression_ExtendedTextLiteral}, {textSyntax->TypeFuncNULL}, }, { KSymbol_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t float_defineSyntax(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { /* Use Syntax.Number package's Parser to parsing FloatLiteral */ KImportPackage(ns, "Syntax.Number", trace); kSyntax *numberSyntax = kSyntax_(ns, KSymbol_NumberPattern); KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("$Float"), SYNFLAG_CTypeFunc, 0, 0, {numberSyntax->ParseFuncNULL}, {SUGARFUNC TypeCheck_Float}, KonohaChar_Digit, {numberSyntax->TokenFuncNULL}}, { KSymbol_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t untyped_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KRequirePackage("Type.StaticVar", trace); kSyntax *assignSyntax = kSyntax_(KNULL(NameSpace), KSymbol_LET); KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("="), SYNFLAG_NodeLeftJoinOp2, assignSyntax->precedence_op2, assignSyntax->precedence_op1, {assignSyntax->ParseFuncNULL}, {KSugarFunc(ns, TypeCheck_UntypedAssign)}}, { KSymbol_END, }, /* sentinental */ }; KLIB kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); return true; }
static kbool_t Exception_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_METHOD MethodData[] = { _Public, _F(Exception_new), KType_Exception, KType_Exception, KMethodName_("new"), 0, _Public|_Hidden, _F(System_throw), KType_void, KType_System, KMethodName_("throw"), 1, KType_Exception, KFieldName_("e"), _Public|_Hidden, _F(System_getThrownException), KType_Exception, KType_System, KMethodName_("getThrownException"), 0, DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("try"), SYNFLAG_CTypeFunc, 0, 0, {SUGAR patternParseFunc}, {SUGARFUNC Statement_try}}, { KSymbol_("catch"), SYNFLAG_CTypeFunc, 0, 0, {SUGAR patternParseFunc}, {SUGARFUNC Statement_catch}}, { KSymbol_("finally"), SYNFLAG_CTypeFunc, 0, 0, {SUGAR patternParseFunc}, {SUGARFUNC Statement_finally}}, { KSymbol_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("try")), "\"try\" $Node [ \"catch\" \"(\" $Type $Symbol \")\" catch: $Node ] [ \"finally\" finally: $Node ]", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("catch")), "\"catch\" \"(\" $Type $Symbol \")\" $Node", 0, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("finally")), "\"finally\" $Node", 0, trace); return true; }
// -------------------------------------------------------------------------- static kbool_t ClosureModel_PackupNameSpace(KonohaContext *kctx, kNameSpace *ns, int option, KTraceInfo *trace) { KDEFINE_SYNTAX SYNTAX[] = { { KSymbol_("function"), SYNFLAG_CTypeFunc, 0, Precedence_CStyleAssign, {SUGAR patternParseFunc}, {SUGARFUNC TypeCheck_Closure}}, { KSymbol_END, }, }; SUGAR kNameSpace_DefineSyntax(kctx, ns, SYNTAX, trace); SUGAR kSyntax_AddPattern(kctx, kSyntax_(ns, KSymbol_("function")), "\"function\" $Param [$Type] $Block", 0, NULL); KDEFINE_METHOD MethodData[] = { _Public|_Hidden, _F(Func_Create), KType_Func, KType_Func, KMethodName_("_Create"), 2, KType_Object, KFieldName_("env"), KType_Method, KFieldName_("mtd"), DEND, }; KLIB kNameSpace_LoadMethodData(kctx, ns, MethodData, trace); return true; }
static void FilterDefinedParam(KonohaContext *kctx, kNameSpace *ns, kArray *tokenList, int beginIdx, int endIdx) { int i; for(i = beginIdx; i < endIdx; i++) { if(i + 1 == endIdx || tokenList->TokenItems[i+1]->resolvedSyntaxInfo->keyword == KSymbol_COMMA) { kTokenVar *tk = tokenList->TokenVarItems[i]; if(tk->resolvedSyntaxInfo->keyword != KSymbol_SymbolPattern) { // defined tk->resolvedSyntaxInfo = kSyntax_(ns, KSymbol_TextPattern); // switch to text pattern } i++; } while(i < endIdx) { kTokenVar *tk = tokenList->TokenVarItems[i]; i++; if(tk->resolvedSyntaxInfo->keyword == KSymbol_COMMA) break; } } }
static KMETHOD Expression_ExtendedTextLiteral(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(expr, tokenList, beginIdx, opIdx, endIdx); kNameSpace *ns = kNode_ns(expr); kToken *tk = tokenList->TokenItems[opIdx]; INIT_GCSTACK(); kString *text = remove_escapes(kctx, tk); if(beginIdx != opIdx) { /* FIXME */ assert(0 && "FIXME"); KReturnUnboxValue(-1); } if(text == NULL) { /* text contain unsupported escape sequences */ RESET_GCSTACK(); KReturnUnboxValue(-1); } const char *str = kString_text(text); const char *end = NULL; const char *start = strstr(str, "${"); if(start == NULL) { /* text does not contain Interpolation expressions */ RESET_GCSTACK(); KReturnUnboxValue(beginIdx+1); } kSyntax *addSyntax = kSyntax_(ns, KSymbol_("+")); kTokenVar *opToken = tokenList->TokenVarItems[beginIdx]; opToken->symbol = KSymbol_("+"); opToken->text = KLIB new_kString(kctx, OnGcStack, "+", 1, 0); KFieldSet(opToken, opToken->resolvedSyntaxInfo, addSyntax); SUGAR kNode_Op(kctx, expr, opToken, 0); /* [before] "aaa${bbb}ccc" * [after] "" + "aaa" + bbb + "ccc" */ SUGAR kNode_AddNode(kctx, expr, new_ConstNode(kctx, ns, NULL, UPCAST(TS_EMPTY))); while(true) { start = strstr(str, "${"); if(start == NULL) break; if(start == strstr(str, "${}")) { str += 3; continue; } end = strchr(start, '}'); if(end == NULL) break; kNode *newexpr = ParseSource(kctx, ns, start+2, end-(start+2)); if(start - str > 0) { kNode *first = new_ConstNode(kctx, ns, NULL, UPCAST(KLIB new_kString(kctx, OnGcStack, str, (start - str), 0))); SUGAR kNode_AddNode(kctx, expr, first); } SUGAR kNode_AddNode(kctx, expr, newexpr); str = end + 1; } if((start == NULL) || (start != NULL && end == NULL)) { kNode *rest = new_ConstNode(kctx, ns, KClass_String, UPCAST(KLIB new_kString(kctx, OnGcStack, str, strlen(str), 0))); SUGAR kNode_AddNode(kctx, expr, rest); } /* (+ 1 2 3 4) => (+ (+ (+ 1 2) 3 ) 4) */ int i, size = kNode_GetNodeListSize(kctx, expr); assert(size > 2); kNode *leftNode = kNode_At(expr, 1), *rightNode; for(i = 2; i < size-1; i++) { kNode *node = KNewNode(ns); rightNode = kNode_At(expr, i); SUGAR kNode_Op(kctx, node, opToken, 2, leftNode, rightNode); leftNode = node; } rightNode = kNode_At(expr, i); KLIB kArray_Clear(kctx, expr->NodeList, 1); KLIB kArray_Add(kctx, expr->NodeList, leftNode); KLIB kArray_Add(kctx, expr->NodeList, rightNode); RESET_GCSTACK(); KReturnUnboxValue(beginIdx+1); }