From 52f75786716e0c3bdf1ab77cbc8102bc8b045403 Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 2 Jun 2018 05:22:30 +0900 Subject: [PATCH 01/19] Add the 'super' keyword. --- src/compiler/analyze.c | 171 +++++++++++++++++----------------------- src/compiler/assemble.c | 18 +++-- src/compiler/ast.c | 2 +- src/compiler/ast.h | 2 +- src/compiler/parse.c | 70 ++++++++++++---- test/kn/test0017.kn | 6 +- 6 files changed, 145 insertions(+), 124 deletions(-) diff --git a/src/compiler/analyze.c b/src/compiler/analyze.c index 69d59010..0a9b3082 100644 --- a/src/compiler/analyze.c +++ b/src/compiler/analyze.c @@ -77,7 +77,7 @@ static SAstFunc* SearchMain(void); static const void* ResolveIdentifierCallback(const Char* key, const void* value, void* param); static void ResolveIdentifierRecursion(const Char* src, const SAst* scope); static void InitAst(SAst* ast, EAstTypeId type_id, const SPos* pos); -static SList* RefreshStats(SList* stats, SAstType* ret_type); +static SList* RefreshStats(SList* stats, SAstType* ret_type, SAstFunc* parent_func); static Bool CmpType(const SAstType* type1, const SAstType* type2); static Bool IsComparable(const SAstType* type, Bool less_or_greater); static U64 BitCast(int size, U64 n); @@ -102,18 +102,18 @@ static void RebuildClass(SAstClass* ast); static void RebuildEnum(SAstEnum* ast); static void RebuildEnumElement(SAstExpr* enum_element, SAstType* type); static void RebuildArg(SAstArg* ast); -static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type); -static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type); -static SAstStat* RebuildSwitch(SAstStatSwitch* ast, SAstType* ret_type); -static SAstStat* RebuildWhile(SAstStatWhile* ast, SAstType* ret_type); -static SAstStat* RebuildFor(SAstStatFor* ast, SAstType* ret_type); -static SAstStat* RebuildTry(SAstStatTry* ast, SAstType* ret_type); +static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func); +static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type, SAstFunc* parent_func); +static SAstStat* RebuildSwitch(SAstStatSwitch* ast, SAstType* ret_type, SAstFunc* parent_func); +static SAstStat* RebuildWhile(SAstStatWhile* ast, SAstType* ret_type, SAstFunc* parent_func); +static SAstStat* RebuildFor(SAstStatFor* ast, SAstType* ret_type, SAstFunc* parent_func); +static SAstStat* RebuildTry(SAstStatTry* ast, SAstType* ret_type, SAstFunc* parent_func); static SAstStat* RebuildThrow(SAstStatThrow* ast); -static SAstStat* RebuildBlock(SAstStatBlock* ast, SAstType* ret_type); +static SAstStat* RebuildBlock(SAstStatBlock* ast, SAstType* ret_type, SAstFunc* parent_func); static SAstStat* RebuildRet(SAstStatRet* ast, SAstType* ret_type); static SAstStat* RebuildDo(SAstStatDo* ast); -static SAstStat* RebuildBreak(SAstStat* ast, SAstType* ret_type); -static SAstStat* RebuildSkip(SAstStat* ast, SAstType* ret_type); +static SAstStat* RebuildBreak(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func); +static SAstStat* RebuildSkip(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func); static SAstStat* RebuildAssert(SAstStatAssert* ast); static SAstType* RebuildType(SAstType* ast, SAstAlias* parent_alias); static SAstExpr* RebuildExpr(SAstExpr* ast, Bool nullable); @@ -348,14 +348,14 @@ static void InitAstExpr(SAstExpr* ast, EAstTypeId type_id, const SPos* pos) ast->VarKind = AstExprVarKind_Unknown; } -static SList* RefreshStats(SList* stats, SAstType* ret_type) +static SList* RefreshStats(SList* stats, SAstType* ret_type, SAstFunc* parent_func) { SList* stats2 = ListNew(); { SListNode* ptr = stats->Top; while (ptr != NULL) { - SAstStat* stat = RebuildStat((SAstStat*)ptr->Data, ret_type); + SAstStat* stat = RebuildStat((SAstStat*)ptr->Data, ret_type, parent_func); if (stat != NULL) ListAdd(stats2, stat); ptr = ptr->Next; @@ -389,8 +389,6 @@ static Bool CmpType(const SAstType* type1, const SAstType* type2) SAstTypeFunc* func2 = (SAstTypeFunc*)type2; SListNode* ptr1 = func1->Args->Top; SListNode* ptr2 = func2->Args->Top; - if (func1->FuncAttr != func2->FuncAttr) - return False; while (ptr1 != NULL && ptr2 != NULL) { SAstTypeFuncArg* arg1 = (SAstTypeFuncArg*)ptr1->Data; @@ -520,7 +518,7 @@ static SAstFunc* AddSpecialFunc(SAstClass* class_, const Char* name) { // These functions override functions of the root class. SAstClassItem* item = (SAstClassItem*)Alloc(sizeof(SAstClassItem)); - item->Override = 1; + item->Override = True; item->Def = (SAst*)func; item->ParentItem = NULL; item->Addr = -1; @@ -946,10 +944,10 @@ static void RebuildRoot(SAstRoot* ast) assign->Children[1] = var->Var->Expr; do_->Expr = (SAstExpr*)assign; } - ListAdd(init_vars->Stats, RebuildStat((SAstStat*)do_, NULL)); + ListAdd(init_vars->Stats, RebuildStat((SAstStat*)do_, NULL, NULL)); } } - if (IsRef(var->Var->Type)) + if (var->Var->Type != NULL && IsRef(var->Var->Type)) { // Add finalization processing of global variables to '_finVars'. SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo)); @@ -978,7 +976,7 @@ static void RebuildRoot(SAstRoot* ast) } do_->Expr = (SAstExpr*)assign; } - ListAdd(fin_vars->Stats, RebuildStat((SAstStat*)do_, NULL)); + ListAdd(fin_vars->Stats, RebuildStat((SAstStat*)do_, NULL, NULL)); } } else @@ -1024,7 +1022,7 @@ static void RebuildFunc(SAstFunc* ast) } if (ast->Ret != NULL) ast->Ret = RebuildType(ast->Ret, NULL); - ast->Stats = RefreshStats(ast->Stats, ast->Ret); + ast->Stats = RefreshStats(ast->Stats, ast->Ret, ast); } static void RebuildVar(SAstVar* ast) @@ -1133,7 +1131,7 @@ static void RebuildClass(SAstClass* ast) } if (parent_item == NULL) { - if (item->Override != 0) + if (item->Override) { Err(L"EA0005", item->Def->Pos, member_name); return; @@ -1141,7 +1139,7 @@ static void RebuildClass(SAstClass* ast) } else { - if (item->Override == 0) + if (!item->Override) { Err(L"EA0006", item->Def->Pos, member_name); return; @@ -1188,7 +1186,7 @@ static void RebuildClass(SAstClass* ast) if (wcscmp(member_name, L"_dtor") == 0 || wcscmp(member_name, L"_copy") == 0 || wcscmp(member_name, L"_toBin") == 0 || wcscmp(member_name, L"_fromBin") == 0) { ASSERT(item->Def->TypeId == AstTypeId_Func); - if (item->Override != 0 && (((SAstFunc*)item->Def)->FuncAttr & FuncAttr_Force) == 0) + if (item->Override && (((SAstFunc*)item->Def)->FuncAttr & FuncAttr_Force) == 0) { Err(L"EA0010", item->Def->Pos, member_name); return; @@ -1210,49 +1208,7 @@ static void RebuildClass(SAstClass* ast) // Analyze functions and variables in classes because they can be referred to as instances. SAst* def = item->Def; if (def->TypeId == AstTypeId_Func) - { - if (item->Override == 2) - { - // Call its parent's function. - SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo)); - InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos); - { - SAstExprCall* call = (SAstExprCall*)Alloc(sizeof(SAstExprCall)); - InitAstExpr((SAstExpr*)call, AstTypeId_ExprCall, ((SAst*)ast)->Pos); - { - SAstExpr* expr = (SAstExpr*)Alloc(sizeof(SAstExpr)); - InitAstExpr(expr, AstTypeId_ExprRef, ((SAst*)ast)->Pos); - ((SAst*)expr)->RefItem = item->ParentItem->Def; - call->Func = expr; - } - call->Args = ListNew(); - { - SListNode* node = ((SAstFunc*)item->Def)->Args->Top; - while (node != NULL) - { - SAstArg* arg = (SAstArg*)node->Data; - { - SAstExprCallArg* expr = (SAstExprCallArg*)Alloc(sizeof(SAstExprCallArg)); - { - SAstExpr* expr2 = (SAstExpr*)Alloc(sizeof(SAstExpr)); - InitAstExpr(expr2, AstTypeId_ExprRef, ((SAst*)ast)->Pos); - ((SAst*)expr2)->RefName = ((SAst*)arg)->Name; - ((SAst*)expr2)->RefItem = (SAst*)arg; - expr->Arg = expr2; - expr->RefVar = arg->RefVar; - expr->SkipVar = NULL; - } - ListAdd(call->Args, expr); - } - node = node->Next; - } - } - do_->Expr = (SAstExpr*)call; - } - ListIns(((SAstFunc*)def)->Stats, ((SAstFunc*)def)->Stats->Top, do_); - } RebuildFunc((SAstFunc*)def); - } else if (def->TypeId == AstTypeId_Var) RebuildVar((SAstVar*)def); } @@ -1786,7 +1742,7 @@ static void RebuildArg(SAstArg* ast) } } -static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type) +static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func) { switch (((SAst*)ast)->TypeId) { @@ -1799,9 +1755,30 @@ static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type) case AstTypeId_StatVar: { SAstStatVar* ast2 = (SAstStatVar*)ast; - if (ast2->Def->Var->Expr == NULL) - return NULL; RebuildVar(ast2->Def); + if (((SAst*)ast2->Def->Var)->Name != NULL && wcscmp(((SAst*)ast2->Def->Var)->Name, L"super") == 0) + { + ASSERT(parent_func != NULL && ((SAst*)parent_func)->Name != NULL); + ASSERT(((SAst*)((SAstArg*)ast2->Def->Var)->Type)->TypeId == AstTypeId_TypeFunc); + SAstClass* ref_class = (SAstClass*)((SAst*)((SAstTypeFuncArg*)((SAstTypeFunc*)((SAstArg*)ast2->Def->Var)->Type)->Args->Top->Data)->Arg)->RefItem; + ASSERT(((SAst*)ref_class)->TypeId == AstTypeId_Class); + SListNode* ptr = ref_class->Items->Top; + while (ptr != NULL) + { + const SAstClassItem* item = (const SAstClassItem*)ptr->Data; + if (item->Def->Name != NULL && wcscmp(item->Def->Name, ((SAst*)parent_func)->Name) == 0) // TODO: + { + ASSERT(item->Override); + SAstExpr* ast_ref = (SAstExpr*)Alloc(sizeof(SAstExpr)); + InitAstExpr(ast_ref, AstTypeId_ExprRef, ((SAst*)ast)->Pos); + ((SAst*)ast_ref)->RefItem = item->ParentItem->Def; + ast2->Def->Var->Expr = ast_ref; + break; + } + ptr = ptr->Next; + } + ASSERT(ptr != NULL); + } if (ast2->Def->Var->Expr == NULL) return NULL; { @@ -1822,21 +1799,21 @@ static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type) ast_do->Expr = (SAstExpr*)ast_assign; } ast2->Def->Var->Expr = NULL; - ast = RebuildStat((SAstStat*)ast_do, ret_type); + ast = RebuildStat((SAstStat*)ast_do, ret_type, parent_func); } } break; - case AstTypeId_StatIf: ast = RebuildIf((SAstStatIf*)ast, ret_type); break; - case AstTypeId_StatSwitch: ast = RebuildSwitch((SAstStatSwitch*)ast, ret_type); break; - case AstTypeId_StatWhile: ast = RebuildWhile((SAstStatWhile*)ast, ret_type); break; - case AstTypeId_StatFor: ast = RebuildFor((SAstStatFor*)ast, ret_type); break; - case AstTypeId_StatTry: ast = RebuildTry((SAstStatTry*)ast, ret_type); break; + case AstTypeId_StatIf: ast = RebuildIf((SAstStatIf*)ast, ret_type, parent_func); break; + case AstTypeId_StatSwitch: ast = RebuildSwitch((SAstStatSwitch*)ast, ret_type, parent_func); break; + case AstTypeId_StatWhile: ast = RebuildWhile((SAstStatWhile*)ast, ret_type, parent_func); break; + case AstTypeId_StatFor: ast = RebuildFor((SAstStatFor*)ast, ret_type, parent_func); break; + case AstTypeId_StatTry: ast = RebuildTry((SAstStatTry*)ast, ret_type, parent_func); break; case AstTypeId_StatThrow: ast = RebuildThrow((SAstStatThrow*)ast); break; - case AstTypeId_StatBlock: ast = RebuildBlock((SAstStatBlock*)ast, ret_type); break; + case AstTypeId_StatBlock: ast = RebuildBlock((SAstStatBlock*)ast, ret_type, parent_func); break; case AstTypeId_StatRet: ast = RebuildRet((SAstStatRet*)ast, ret_type); break; case AstTypeId_StatDo: ast = RebuildDo((SAstStatDo*)ast); break; - case AstTypeId_StatBreak: ast = RebuildBreak((SAstStat*)ast, ret_type); break; - case AstTypeId_StatSkip: ast = RebuildSkip((SAstStat*)ast, ret_type); break; + case AstTypeId_StatBreak: ast = RebuildBreak((SAstStat*)ast, ret_type, parent_func); break; + case AstTypeId_StatSkip: ast = RebuildSkip((SAstStat*)ast, ret_type, parent_func); break; case AstTypeId_StatAssert: ast = RebuildAssert((SAstStatAssert*)ast); break; default: ASSERT(False); @@ -1848,7 +1825,7 @@ static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type) return ast; } -static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type) +static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; @@ -1856,7 +1833,7 @@ static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type) ast->Cond = RebuildExpr(ast->Cond, False); if (ast->Cond != NULL && !IsBool(ast->Cond->Type)) Err(L"EA0016", ((SAst*)ast->Cond)->Pos); - ast->StatBlock = (SAstStatBlock*)RebuildBlock(ast->StatBlock, ret_type); + ast->StatBlock = (SAstStatBlock*)RebuildBlock(ast->StatBlock, ret_type, parent_func); { SListNode* ptr = ast->ElIfs->Top; while (ptr != NULL) @@ -1865,12 +1842,12 @@ static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type) elif->Cond = RebuildExpr(elif->Cond, False); if (elif->Cond != NULL && !IsBool(elif->Cond->Type)) Err(L"EA0017", ((SAst*)elif->Cond)->Pos); - elif->StatBlock = (SAstStatBlock*)RebuildBlock(elif->StatBlock, ret_type); + elif->StatBlock = (SAstStatBlock*)RebuildBlock(elif->StatBlock, ret_type, parent_func); ptr = ptr->Next; } } if (ast->ElseStatBlock != NULL) - ast->ElseStatBlock = (SAstStatBlock*)RebuildBlock(ast->ElseStatBlock, ret_type); + ast->ElseStatBlock = (SAstStatBlock*)RebuildBlock(ast->ElseStatBlock, ret_type, parent_func); if (ast->Cond != NULL) { // Optimize the code. @@ -1917,7 +1894,7 @@ static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type) return (SAstStat*)ast; } -static SAstStat* RebuildSwitch(SAstStatSwitch* ast, SAstType* ret_type) +static SAstStat* RebuildSwitch(SAstStatSwitch* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; @@ -1959,16 +1936,16 @@ static SAstStat* RebuildSwitch(SAstStatSwitch* ast, SAstType* ret_type) } ptr2 = ptr2->Next; } - case_->StatBlock = (SAstStatBlock*)RebuildBlock(case_->StatBlock, ret_type); + case_->StatBlock = (SAstStatBlock*)RebuildBlock(case_->StatBlock, ret_type, parent_func); ptr = ptr->Next; } } if (ast->DefaultStatBlock != NULL) - ast->DefaultStatBlock = (SAstStatBlock*)RebuildBlock(ast->DefaultStatBlock, ret_type); + ast->DefaultStatBlock = (SAstStatBlock*)RebuildBlock(ast->DefaultStatBlock, ret_type, parent_func); return (SAstStat*)ast; } -static SAstStat* RebuildWhile(SAstStatWhile* ast, SAstType* ret_type) +static SAstStat* RebuildWhile(SAstStatWhile* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; @@ -1979,11 +1956,11 @@ static SAstStat* RebuildWhile(SAstStatWhile* ast, SAstType* ret_type) if (ast->Cond != NULL && !IsBool(ast->Cond->Type)) Err(L"EA0020", ((SAst*)ast->Cond)->Pos); } - ast->Stats = RefreshStats(ast->Stats, ret_type); + ast->Stats = RefreshStats(ast->Stats, ret_type, parent_func); return (SAstStat*)ast; } -static SAstStat* RebuildFor(SAstStatFor* ast, SAstType* ret_type) +static SAstStat* RebuildFor(SAstStatFor* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; @@ -2008,17 +1985,17 @@ static SAstStat* RebuildFor(SAstStatFor* ast, SAstType* ret_type) if (*((S64*)((SAstExprValue*)ast->Step)->Value) == 0) Err(L"EA0025", ((SAst*)ast->Step)->Pos); } - ast->Stats = RefreshStats(ast->Stats, ret_type); + ast->Stats = RefreshStats(ast->Stats, ret_type, parent_func); return (SAstStat*)ast; } -static SAstStat* RebuildTry(SAstStatTry* ast, SAstType* ret_type) +static SAstStat* RebuildTry(SAstStatTry* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; ((SAst*)ast)->AnalyzedCache = (SAst*)ast; RebuildArg(((SAstStatBreakable*)ast)->BlockVar); - ast->StatBlock = (SAstStatBlock*)RebuildBlock(ast->StatBlock, ret_type); + ast->StatBlock = (SAstStatBlock*)RebuildBlock(ast->StatBlock, ret_type, parent_func); if (ast->Catches->Len != 0) { SListNode* ptr = ast->Catches->Top; @@ -2040,12 +2017,12 @@ static SAstStat* RebuildTry(SAstStatTry* ast, SAstType* ret_type) } ptr2 = ptr2->Next; } - catch_->StatBlock = (SAstStatBlock*)RebuildBlock(catch_->StatBlock, ret_type); + catch_->StatBlock = (SAstStatBlock*)RebuildBlock(catch_->StatBlock, ret_type, parent_func); ptr = ptr->Next; } } if (ast->FinallyStatBlock != NULL) - ast->FinallyStatBlock = (SAstStatBlock*)RebuildBlock(ast->FinallyStatBlock, ret_type); + ast->FinallyStatBlock = (SAstStatBlock*)RebuildBlock(ast->FinallyStatBlock, ret_type, parent_func); return (SAstStat*)ast; } @@ -2060,12 +2037,12 @@ static SAstStat* RebuildThrow(SAstStatThrow* ast) return (SAstStat*)ast; } -static SAstStat* RebuildBlock(SAstStatBlock* ast, SAstType* ret_type) +static SAstStat* RebuildBlock(SAstStatBlock* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; ((SAst*)ast)->AnalyzedCache = (SAst*)ast; - ast->Stats = RefreshStats(ast->Stats, ret_type); + ast->Stats = RefreshStats(ast->Stats, ret_type, parent_func); return (SAstStat*)ast; } @@ -2107,7 +2084,7 @@ static SAstStat* RebuildDo(SAstStatDo* ast) return (SAstStat*)ast; } -static SAstStat* RebuildBreak(SAstStat* ast, SAstType* ret_type) +static SAstStat* RebuildBreak(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; @@ -2117,11 +2094,11 @@ static SAstStat* RebuildBreak(SAstStat* ast, SAstType* ret_type) Err(L"EA0033", ((SAst*)ast)->Pos); return (SAstStat*)DummyPtr; } - ((SAst*)ast)->RefItem = (SAst*)RebuildStat((SAstStat*)((SAst*)ast)->RefItem, ret_type); + ((SAst*)ast)->RefItem = (SAst*)RebuildStat((SAstStat*)((SAst*)ast)->RefItem, ret_type, parent_func); return (SAstStat*)ast; } -static SAstStat* RebuildSkip(SAstStat* ast, SAstType* ret_type) +static SAstStat* RebuildSkip(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func) { if (((SAst*)ast)->AnalyzedCache != NULL) return (SAstStat*)((SAst*)ast)->AnalyzedCache; @@ -2131,7 +2108,7 @@ static SAstStat* RebuildSkip(SAstStat* ast, SAstType* ret_type) Err(L"EA0034", ((SAst*)ast)->Pos); return (SAstStat*)DummyPtr; } - ((SAst*)ast)->RefItem = (SAst*)RebuildStat((SAstStat*)((SAst*)ast)->RefItem, ret_type); + ((SAst*)ast)->RefItem = (SAst*)RebuildStat((SAstStat*)((SAst*)ast)->RefItem, ret_type, parent_func); return (SAstStat*)ast; } diff --git a/src/compiler/assemble.c b/src/compiler/assemble.c index b6c23db5..05ce411b 100644 --- a/src/compiler/assemble.c +++ b/src/compiler/assemble.c @@ -130,6 +130,7 @@ static void SetTypeId(EReg reg, const SAstType* type); static int SetTypeIdRecursion(U8* ptr, int idx, const SAstType* type); static void SetTypeIdForFromBin(EReg reg, const SAstType* type); static void SetTypeIdForFromBinRecursion(int* idx_type, U8* data_type, int* idx_class, S64** data_class, const SAstType* type); +static void ExpandMe(SAstExprDot* dot, int reg_i); static void AssembleFunc(SAstFunc* ast, Bool entry); static void AssembleStats(SList* asts); static void AssembleIf(SAstStatIf* ast); @@ -773,7 +774,7 @@ static S64* RefClass(SAstClass* class_) SAstClassItem* item = (SAstClassItem*)ptr->Data; if ((item->Def->TypeId & AstTypeId_Func) == AstTypeId_Func) { - if (item->Override != 0) + if (item->Override) item->Addr = item->ParentItem->Addr; else { @@ -1543,6 +1544,13 @@ static void SetTypeIdForFromBinRecursion(int* idx_type, U8* data_type, int* idx_ return; } +static void ExpandMe(SAstExprDot* dot, int reg_i) +{ + ListAdd(PackAsm->Asms, AsmMOV(ValReg(8, RegI[reg_i]), ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x08))); + ListAdd(PackAsm->Asms, AsmLEA(ValReg(8, RegI[reg_i]), ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x08 + dot->ClassItem->Addr))); + ListAdd(PackAsm->Asms, AsmADD(ValReg(8, RegI[reg_i]), ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00))); +} + static void AssembleFunc(SAstFunc* ast, Bool entry) { ASSERT(((SAst*)ast)->AnalyzedCache != NULL); @@ -3597,9 +3605,7 @@ static void AssembleExprCall(SAstExprCall* ast, int reg_i, int reg_f) ASSERT(IsRef(((SAstExprCallArg*)ptr->Data)->Arg->Type) && !((SAstExprCallArg*)ptr->Data)->RefVar); GcInc(0); // Expand 'me'. - ListAdd(PackAsm->Asms, AsmMOV(ValReg(8, RegI[0]), ValMemS(8, ValReg(8, RegI[0]), NULL, 0x08))); - ListAdd(PackAsm->Asms, AsmLEA(ValReg(8, RegI[0]), ValMemS(8, ValReg(8, RegI[0]), NULL, 0x08 + ((SAstExprDot*)ast->Func)->ClassItem->Addr))); - ListAdd(PackAsm->Asms, AsmADD(ValReg(8, RegI[0]), ValMemS(8, ValReg(8, RegI[0]), NULL, 0x00))); + ExpandMe((SAstExprDot*)ast->Func, 0); } else if ((((SAstTypeFunc*)ast->Func->Type)->FuncAttr & FuncAttr_AnyType) != 0 && ptr == ast->Args->Top->Next) { @@ -3729,9 +3735,7 @@ static void AssembleExprDot(SAstExprDot* ast, int reg_i, int reg_f, Bool expand_ if (expand_me) { // In case of method call, 'me' should not be expanded. - ListAdd(PackAsm->Asms, AsmMOV(ValReg(8, RegI[0]), ValMemS(8, ValReg(8, RegI[0]), NULL, 0x08))); - ListAdd(PackAsm->Asms, AsmLEA(ValReg(8, RegI[0]), ValMemS(8, ValReg(8, RegI[0]), NULL, 0x08 + ast->ClassItem->Addr))); - ListAdd(PackAsm->Asms, AsmADD(ValReg(8, RegI[0]), ValMemS(8, ValReg(8, RegI[0]), NULL, 0x00))); + ExpandMe(ast, reg_i); } } } diff --git a/src/compiler/ast.c b/src/compiler/ast.c index c26b5a06..ac87b391 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -502,7 +502,7 @@ static void DumpAstClass(const SAstClass* ast) const SAstClassItem* item = (const SAstClassItem*)ptr->Data; PrintTab(); fwprintf(FilePtr, L"Public ? L"True" : L"False"); - fwprintf(FilePtr, L" Override=\"%d\"", item->Override); + fwprintf(FilePtr, L" Override=\"%s\"", item->Override ? L"True" : L"False"); fwprintf(FilePtr, L" ParentItem=\"%s\"", item->ParentItem == NULL ? L"(Null)" : L"(Ptr)"); fwprintf(FilePtr, L" />\n"); ASSERT(item->Def != NULL); diff --git a/src/compiler/ast.h b/src/compiler/ast.h index 1c833761..ac65296d 100644 --- a/src/compiler/ast.h +++ b/src/compiler/ast.h @@ -163,7 +163,7 @@ typedef struct SAstAlias typedef struct SAstClassItem { Bool Public; - U8 Override; // 0 = none, 1 = override, 2 = override and call its parent method. + Bool Override; SAst* Def; struct SAstClassItem* ParentItem; S64 Addr; diff --git a/src/compiler/parse.c b/src/compiler/parse.c index 35b05efd..d6319329 100644 --- a/src/compiler/parse.c +++ b/src/compiler/parse.c @@ -50,6 +50,7 @@ static const Char* Reserved[] = L"ret", L"skip", L"stack", + L"super", L"switch", L"throw", L"to", @@ -153,7 +154,7 @@ static void AddSrc(const Char* name); static Bool IsReserved(const Char* word); static SAstStatBlock* ParseDummyBlock(SAstStat** out_stat, EAstTypeId* out_type_id, EAstTypeId type_id, SAst* block); static SAstRoot* ParseRoot(SAstRoot* ast); -static SAstFunc* ParseFunc(const Char* parent_class); +static SAstFunc* ParseFunc(const Char* parent_class, Bool overridden); static SAstVar* ParseVar(EAstArgKind kind, const Char* parent_class); static SAstConst* ParseConst(void); static SAstAlias* ParseAlias(void); @@ -1393,7 +1394,7 @@ static SAstRoot* ParseRoot(SAstRoot* ast) int col = Col; const Char* id = ReadIdentifier(True, False); if (wcscmp(id, L"func") == 0) - child = (SAst*)ParseFunc(NULL); + child = (SAst*)ParseFunc(NULL, False); else if (wcscmp(id, L"var") == 0) child = (SAst*)ParseVar(AstArgKind_Global, NULL); else if (wcscmp(id, L"const") == 0) @@ -1432,7 +1433,7 @@ static SAstRoot* ParseRoot(SAstRoot* ast) return ast; } -static SAstFunc* ParseFunc(const Char* parent_class) +static SAstFunc* ParseFunc(const Char* parent_class, Bool overridden) { SAstFunc* ast = (SAstFunc*)Alloc(sizeof(SAstFunc)); ast->DllName = NULL; @@ -1580,6 +1581,49 @@ static SAstFunc* ParseFunc(const Char* parent_class) if (c != L'\n') NextCharErr(L'\n', c); } + if (overridden) + { + SAstStatVar* stat_var = (SAstStatVar*)Alloc(sizeof(SAstStatVar)); + { + InitAst((SAst*)stat_var, AstTypeId_StatVar, ((SAst*)ast)->Pos, NULL, False, False); + SAstVar* var = (SAstVar*)Alloc(sizeof(SAstVar)); + { + InitAst((SAst*)var, AstTypeId_Var, ((SAst*)ast)->Pos, NULL, False, False); + SAstArg* arg = (SAstArg*)Alloc(sizeof(SAstArg)); + { + InitAst((SAst*)arg, AstTypeId_Arg, ((SAst*)ast)->Pos, NULL, False, False); + ((SAst*)arg)->Name = L"super"; + arg->Addr = NewAddr(); + arg->Expr = NULL; + arg->Kind = AstArgKind_LocalArg; + arg->RefVar = False; + AddScopeName((SAst*)arg, False); + { + SAstTypeFunc* type = (SAstTypeFunc*)Alloc(sizeof(SAstTypeFunc)); + InitAst((SAst*)type, AstTypeId_TypeFunc, ((SAst*)ast)->Pos, NULL, False, False); + type->FuncAttr = ast->FuncAttr; + type->Args = ListNew(); + { + SListNode* ptr = ast->Args->Top; + while (ptr != NULL) + { + SAstTypeFuncArg* arg2 = (SAstTypeFuncArg*)Alloc(sizeof(SAstTypeFuncArg)); + arg2->RefVar = ((SAstArg*)ptr->Data)->RefVar; + arg2->Arg = ((SAstArg*)ptr->Data)->Type; + ListAdd(type->Args, arg2); + ptr = ptr->Next; + } + } + type->Ret = ast->Ret; + arg->Type = (SAstType*)type; + } + } + var->Var = arg; + } + stat_var->Def = var; + } + ListAdd(ast->Stats, stat_var); + } for (; ; ) { SAstStat* stat = ParseStat((SAst*)ast); @@ -1683,7 +1727,7 @@ static SAstClass* ParseClass(void) int col = Col; SAstClassItem* item = (SAstClassItem*)Alloc(sizeof(SAstClassItem)); item->Public = False; - item->Override = 0; + item->Override = False; item->ParentItem = NULL; item->Addr = -1; if (c == L'+') @@ -1692,24 +1736,17 @@ static SAstClass* ParseClass(void) FileBuf = c; c = ReadChar(); if (c == L'*') - { - item->Override = 1; - c = ReadChar(); - if (c == L'*') - item->Override = 2; - else - FileBuf = c; - } + item->Override = True; else FileBuf = c; { const Char* s = ReadIdentifier(True, False); const Char* class_name = ((SAst*)ast)->ScopeParent->TypeId == AstTypeId_Root ? NewStr(NULL, L"@%s", ((SAst*)ast)->Name) : ((SAst*)ast)->Name; if (wcscmp(s, L"func") == 0) - item->Def = (SAst*)ParseFunc(class_name); + item->Def = (SAst*)ParseFunc(class_name, item->Override); else if (wcscmp(s, L"var") == 0) { - if (item->Override != 0) + if (item->Override) Err(L"EP0028", NewPos(SrcName, row, col), s); item->Def = (SAst*)ParseVar(AstArgKind_Member, class_name); } @@ -1717,7 +1754,7 @@ static SAstClass* ParseClass(void) { if (item->Public) Err(L"EP0029", NewPos(SrcName, row, col), s); - if (item->Override != 0) + if (item->Override) Err(L"EP0028", NewPos(SrcName, row, col), s); if (wcscmp(s, L"end") == 0) { @@ -2010,7 +2047,7 @@ static SAstStat* ParseStatFunc(void) { SAstStatFunc* ast = (SAstStatFunc*)Alloc(sizeof(SAstStatFunc)); InitAst((SAst*)ast, AstTypeId_StatFunc, NULL, NULL, False, False); - ast->Def = ParseFunc(NULL); + ast->Def = ParseFunc(NULL, False); return (SAstStat*)ast; } @@ -5506,6 +5543,7 @@ static Bool GetKeywordsReadExprValue(const Char** str) GetKeywordsAdd(L"false"); GetKeywordsAdd(L"inf"); GetKeywordsAdd(L"null"); + GetKeywordsAdd(L"super"); GetKeywordsAdd(L"true"); GetKeywordsAddKeywords(L'e'); return True; diff --git a/test/kn/test0017.kn b/test/kn/test0017.kn index 85adad40..e318aacb 100644 --- a/test/kn/test0017.kn +++ b/test/kn/test0017.kn @@ -9,14 +9,16 @@ func main() end class class ObjB(ObjA) - +**func f(str: []char): int + +*func f(str: []char): int + do super(me, str) do cui@print("B" ~ str) ret 2 end func end class class ObjC(ObjB) - +**func f(str: []char): int + +*func f(str: []char): int + do super(me, str) do cui@print("C" ~ str) ret 3 end func From 30598acea2d2432fb1e3092761f94a74f797418b Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 2 Jun 2018 16:46:27 +0900 Subject: [PATCH 02/19] Change syntax of hexadecimal literal. --- package/sys/draw.kn | 22 +-- package/sys/excpt.kn | 38 +++--- package/sys/file.kn | 24 ++-- package/sys/input.kn | 34 ++--- package/sys/kuin.kn | 2 +- package/sys/lib.kn | 16 +-- package/sys/math.kn | 6 +- package/sys/msg.knd | 4 +- package/sys/net.kn | 18 +-- package/sys/regex.kn | 6 +- package/sys/snd.kn | 6 +- package/sys/task.kn | 18 +-- package/sys/undo.kn | 10 +- package/sys/wnd.kn | 64 ++++----- package/sys/xml.kn | 12 +- src/compiler/analyze.c | 20 +-- src/compiler/parse.c | 23 ++-- src/kuin_editor/common.kn | 2 +- src/kuin_editor/doc_ar.kn | 10 +- src/kuin_editor/doc_ar_wnd.kn | 245 ++++++++++++++++++++++------------ src/kuin_editor/doc_src.kn | 53 ++++---- src/kuin_editor/form.kn | 138 +++++++++---------- src/kuin_editor/src.kn | 10 +- test/kn/test0000.kn | 8 +- test/kn/test0001.kn | 48 +++---- test/kn/test0005.kn | 8 +- test/kn/test0009.kn | 16 +-- test/kn/test0012.kn | 8 +- test/kn/test0014.kn | 2 +- test/kn/test0015.kn | 10 +- 30 files changed, 473 insertions(+), 408 deletions(-) diff --git a/package/sys/draw.kn b/package/sys/draw.kn index 94b83203..caf2a01d 100644 --- a/package/sys/draw.kn +++ b/package/sys/draw.kn @@ -1,5 +1,5 @@ -+const white: int :: 16#FFFFFFFF -+const black: int :: 16#FF000000 ++const white: int :: 0xFFFFFFFF ++const black: int :: 0xFF000000 +func [d0001.knd, _target] target(drawCtrl: wnd@Draw) end func @@ -61,15 +61,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _texDraw] draw(dstX: float, dstY: float, srcX: float, srcY: float, srcW: float, srcH: float, color: int) @@ -103,15 +103,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _fontDraw] draw(dstX: float, dstY: float, text: []char, color: int) @@ -155,15 +155,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _objDraw] draw(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex) diff --git a/package/sys/excpt.kn b/package/sys/excpt.kn index a0d4a459..b504c3d6 100644 --- a/package/sys/excpt.kn +++ b/package/sys/excpt.kn @@ -1,19 +1,19 @@ -+const userMin: int :: 16#00000000 -+const userMax: int :: 16#0000FFFF -+const accessViolation: int :: 16#C0000005 -+const noMem: int :: 16#C0000017 -+const floatInvalidOperation: int :: 16#C0000090 -+const intDivideByZero: int :: 16#C0000094 -+const stackOverflow: int :: 16#C00000FD -+const ctrlCExit: int :: 16#C000013A -+const dbgAssertFailed: int :: 16#E9170000 -+const classCastFailed: int :: 16#E9170001 -+const dbgArrayIdxOutOfRange: int :: 16#E9170002 -+const dbgIntOverflow: int :: 16#E9170003 -+const invalidCmp: int :: 16#E9170004 -+const libClassInvalidOperation: int :: 16#E9170005 -+const dbgArgOutDomain: int :: 16#E9170006 -+const fileReadFailed: int :: 16#E9170007 -+const invalidDataFmt: int :: 16#E9170008 -+const deviceInitFailed: int :: 16#E9170009 -+const dbgInoperableState: int :: 16#E917000A ++const userMin: int :: 0x00000000 ++const userMax: int :: 0x0000FFFF ++const accessViolation: int :: 0xC0000005 ++const noMem: int :: 0xC0000017 ++const floatInvalidOperation: int :: 0xC0000090 ++const intDivideByZero: int :: 0xC0000094 ++const stackOverflow: int :: 0xC00000FD ++const ctrlCExit: int :: 0xC000013A ++const dbgAssertFailed: int :: 0xE9170000 ++const classCastFailed: int :: 0xE9170001 ++const dbgArrayIdxOutOfRange: int :: 0xE9170002 ++const dbgIntOverflow: int :: 0xE9170003 ++const invalidCmp: int :: 0xE9170004 ++const libClassInvalidOperation: int :: 0xE9170005 ++const dbgArgOutDomain: int :: 0xE9170006 ++const fileReadFailed: int :: 0xE9170007 ++const invalidDataFmt: int :: 0xE9170008 ++const deviceInitFailed: int :: 0xE9170009 ++const dbgInoperableState: int :: 0xE917000A diff --git a/package/sys/file.kn b/package/sys/file.kn index c609d3d7..cdfc57ca 100644 --- a/package/sys/file.kn +++ b/package/sys/file.kn @@ -9,15 +9,15 @@ end enum end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _streamFin] fin() @@ -70,15 +70,15 @@ end class end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _streamFin] fin() @@ -118,12 +118,12 @@ end func end func +enum SysDir - desktop :: 16#00 - fonts :: 16#14 - appData :: 16#1A - windows :: 16#24 - system32 :: 16#25 - programFiles :: 16#26 + desktop :: 0x00 + fonts :: 0x14 + appData :: 0x1A + windows :: 0x24 + system32 :: 0x25 + programFiles :: 0x26 end enum +func [d0000.knd, _makeDir] makeDir(path: []char): bool diff --git a/package/sys/input.kn b/package/sys/input.kn index b0095003..8d67bced 100644 --- a/package/sys/input.kn +++ b/package/sys/input.kn @@ -18,7 +18,7 @@ end enum +enum Key - esc :: 16#01 + esc :: 0x01 _1 _2 _3 @@ -101,31 +101,31 @@ end enum num3 num0 numPeriod - f11 :: 16#57 + f11 :: 0x57 f12 - kana :: 16#70 - convert :: 16#79 - noConvert :: 16#7B - yen :: 16#7D - circumflex :: 16#90 - kanji :: 16#94 - numEnter :: 16#9C + kana :: 0x70 + convert :: 0x79 + noConvert :: 0x7B + yen :: 0x7D + circumflex :: 0x90 + kanji :: 0x94 + numEnter :: 0x9C ctrlR - numSlash :: 16#B5 - sysRq :: 16#B7 + numSlash :: 0xB5 + sysRq :: 0xB7 altR - pause :: 16#C5 - home :: 16#C7 + pause :: 0xC5 + home :: 0xC7 up pageUp - left :: 16#CB - right :: 16#CD - end_ :: 16#CF + left :: 0xCB + right :: 0xCD + end_ :: 0xCF down pageDown ins del - winL :: 16#DB + winL :: 0xDB winR menu end enum diff --git a/package/sys/kuin.kn b/package/sys/kuin.kn index 8a6ad770..d6152c42 100644 --- a/package/sys/kuin.kn +++ b/package/sys/kuin.kn @@ -6,7 +6,7 @@ end func +func cmp(t: @Class): int - throw 16#E9170004 + throw 0xE9170004 end func func _copy(): @Class diff --git a/package/sys/lib.kn b/package/sys/lib.kn index 4788e084..a4029c2e 100644 --- a/package/sys/lib.kn +++ b/package/sys/lib.kn @@ -8,8 +8,8 @@ end func +func [_exit_code] exitCode(code: int) if(dbg) - if(code < 0 | 16#FFFFFFFF < code) - throw 16#E9170006 + if(code < 0 | 0xFFFFFFFF < code) + throw 0xE9170006 end if end if end func @@ -19,15 +19,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _rndRnd] rnd(min: int, max: int): int @@ -176,15 +176,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _bmSearchFind] find(text: []char, start: int): int diff --git a/package/sys/math.kn b/package/sys/math.kn index b82b0d11..fa6b6ec2 100644 --- a/package/sys/math.kn +++ b/package/sys/math.kn @@ -33,15 +33,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func var row: int diff --git a/package/sys/msg.knd b/package/sys/msg.knd index 8c0c868a..996fb146 100644 --- a/package/sys/msg.knd +++ b/package/sys/msg.knd @@ -110,7 +110,7 @@ EP0015 括弧「(」に対応する「)」があるべき場所に存在しません。 --- EP0016 -数値リテラルに不正な形式の「#」が記述されました。 +数値リテラルに不正な形式の「x」が記述されました。 --- EP0017 数値リテラルに不正な形式の「.」が記述されました。 @@ -119,7 +119,7 @@ EP0018 数値リテラル「%s...」が長すぎます。 1024文字以下でなければなりません。 --- EP0019 -数値リテラルの基数「%d#」は「2#」「8#」「16#」のいずれかでなければなりません。 +16進数リテラルは「0x」としなければなりません。 --- EP0020 浮動小数点リテラル「%s」がオーバーフローもしくはアンダーフローしました。 diff --git a/package/sys/net.kn b/package/sys/net.kn index f96f8fab..66607ceb 100644 --- a/package/sys/net.kn +++ b/package/sys/net.kn @@ -9,15 +9,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0004.knd, _tcpServerFin] fin() @@ -42,15 +42,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0004.knd, _tcpFin] fin() @@ -81,15 +81,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0004.knd, _httpFin] fin() diff --git a/package/sys/regex.kn b/package/sys/regex.kn index 221dc1c0..d664f61b 100644 --- a/package/sys/regex.kn +++ b/package/sys/regex.kn @@ -6,15 +6,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d1002.knd, _regexFind] find(pos: &int, text: []char, start: int): [][]char diff --git a/package/sys/snd.kn b/package/sys/snd.kn index dd507a54..a3a47a52 100644 --- a/package/sys/snd.kn +++ b/package/sys/snd.kn @@ -12,15 +12,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _sndPlay] play() diff --git a/package/sys/task.kn b/package/sys/task.kn index 6b26690d..65b9b06f 100644 --- a/package/sys/task.kn +++ b/package/sys/task.kn @@ -3,15 +3,15 @@ end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _processRun] run(waitUntilExit: bool): int @@ -32,15 +32,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _threadRun] run() @@ -63,15 +63,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0000.knd, _mutexLock] lock() diff --git a/package/sys/undo.kn b/package/sys/undo.kn index 9a520259..2d6a5fc3 100644 --- a/package/sys/undo.kn +++ b/package/sys/undo.kn @@ -14,7 +14,7 @@ end class +func recordBegin() if(dbg & me.state <> 0) do wnd@msgBox(null, "a", "piyo", %none, %ok) - throw 16#E917000A + throw 0xE917000A end if do me.state :: 1 end func @@ -22,7 +22,7 @@ end class +func add(undo: @Cmd, redo: @Cmd) if(dbg & me.state = 0) do wnd@msgBox(null, "b", "piyo", %none, %ok) - throw 16#E917000A + throw 0xE917000A end if do me.bufPtr :: me.bufPtrNext(me.bufPtr) do me.undoBuf[me.bufPtr] :: undo @@ -33,7 +33,7 @@ end class +func recordEnd() if(dbg & me.state = 0) do wnd@msgBox(null, "c", "piyo", %none, %ok) - throw 16#E917000A + throw 0xE917000A end if if(me.state = 2) do me.bufPtr :: me.bufPtrNext(me.bufPtr) @@ -53,7 +53,7 @@ end class +func undo() if(dbg & me.state <> 0) do wnd@msgBox(null, "d", "piyo", %none, %ok) - throw 16#E917000A + throw 0xE917000A end if if(me.undoBuf[me.bufPtrPrev(me.bufPtr)] =& null) ret @@ -70,7 +70,7 @@ end class +func redo() if(dbg & me.state <> 0) do wnd@msgBox(null, "e", "piyo", %none, %ok) - throw 16#E917000A + throw 0xE917000A end if if(me.redoBuf[me.bufPtrNext(me.bufPtr)] =& null) ret diff --git a/package/sys/wnd.kn b/package/sys/wnd.kn index 872343bc..73022178 100644 --- a/package/sys/wnd.kn +++ b/package/sys/wnd.kn @@ -18,8 +18,8 @@ end func dock dockChild } - layered :: 16#10000 - noMinimize :: 16#20000 + layered :: 0x10000 + noMinimize :: 0x20000 end enum +enum Anchor @@ -33,15 +33,15 @@ end enum end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _wndBaseGetPos] getPos(x: &int, y: &int, width: &int, height: &int) @@ -81,7 +81,7 @@ end enum +func find(name: []char): @WndBase if(dbg) if(name =& null) - throw 16#E9170006 + throw 0xE9170006 end if end if ret findRecursion(me, name) @@ -172,8 +172,8 @@ end class +enum ShiftCtrl none - shift :: 16#01 - ctrl :: 16#02 + shift :: 0x01 + ctrl :: 0x02 end enum +class Draw(@WndBase) @@ -511,15 +511,15 @@ end class end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _treeNodeAddChild, _make_instance] addChild(me2: @TreeNode, name: []char): @TreeNode @@ -588,10 +588,10 @@ end class +enum MsgBoxIcon none - err :: 16#10 - question :: 16#20 - warn :: 16#30 - info :: 16#40 + err :: 0x10 + question :: 0x20 + warn :: 0x30 + info :: 0x40 end enum +enum MsgBoxBtn @@ -807,15 +807,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _menuAdd] add(id: int, text: []char) @@ -850,15 +850,15 @@ end func +class TabOrder() *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d0001.knd, _tabOrderChk] chk(key: @Key, shiftCtrl: @ShiftCtrl): bool @@ -874,18 +874,18 @@ end func end func +enum Key - mouseL :: 16#01 + mouseL :: 0x01 mouseR - mouseM :: 16#04 - bs :: 16#08 + mouseM :: 0x04 + bs :: 0x08 tab - enter :: 16#0D - shift :: 16#10 + enter :: 0x0D + shift :: 0x10 ctrl alt pause - esc :: 16#1B - space :: 16#20 + esc :: 0x1B + space :: 0x20 pageUp pageDown end_ @@ -894,9 +894,9 @@ end func up right down - ins :: 16#2D + ins :: 0x2D del - _0 :: 16#30 + _0 :: 0x30 _1 _2 _3 @@ -906,7 +906,7 @@ end func _7 _8 _9 - a :: 16#41 + a :: 0x41 b c d @@ -932,7 +932,7 @@ end func x y z - f1 :: 16#70 + f1 :: 0x70 f2 f3 f4 diff --git a/package/sys/xml.kn b/package/sys/xml.kn index af49e1ec..051b37b2 100644 --- a/package/sys/xml.kn +++ b/package/sys/xml.kn @@ -6,15 +6,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d1003.knd, _xmlSave] save(path: []char, compact: bool): bool @@ -43,15 +43,15 @@ end func end func *func [_force] _copy(): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _toBin(): []bit8 - throw 16#E9170005 + throw 0xE9170005 end func *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class - throw 16#E9170005 + throw 0xE9170005 end func +func [d1003.knd, _xmlNodeSetName] setName(name: []char) diff --git a/src/compiler/analyze.c b/src/compiler/analyze.c index 0a9b3082..a7faba19 100644 --- a/src/compiler/analyze.c +++ b/src/compiler/analyze.c @@ -1317,7 +1317,7 @@ static void RebuildClass(SAstClass* ast) } do_->Expr = (SAstExpr*)assign; } - ListAdd(dtor->Stats, do_); + ListAdd(dtor->Stats, RebuildStat((SAstStat*)do_, dtor->Ret, dtor)); } ptr2 = ptr2->Next; } @@ -1355,7 +1355,7 @@ static void RebuildClass(SAstClass* ast) } var->Def = var2; } - ListAdd(copy->Stats, var); + ListAdd(copy->Stats, RebuildStat((SAstStat*)var, copy->Ret, copy)); { result = (SAstExpr*)Alloc(sizeof(SAstExpr)); InitAstExpr(result, AstTypeId_ExprRef, ((SAst*)ast)->Pos); @@ -1410,7 +1410,7 @@ static void RebuildClass(SAstClass* ast) } do_->Expr = (SAstExpr*)assign; } - ListAdd(copy->Stats, do_); + ListAdd(copy->Stats, RebuildStat((SAstStat*)do_, copy->Ret, copy)); } } ptr2 = ptr2->Next; @@ -1429,7 +1429,7 @@ static void RebuildClass(SAstClass* ast) as->ChildType = copy->Ret; ret->Value = (SAstExpr*)as; } - ListAdd(copy->Stats, ret); + ListAdd(copy->Stats, RebuildStat((SAstStat*)ret, copy->Ret, copy)); } } // The '_toBin' function. @@ -1486,7 +1486,7 @@ static void RebuildClass(SAstClass* ast) } var->Def = var2; } - ListAdd(to_bin->Stats, var); + ListAdd(to_bin->Stats, RebuildStat((SAstStat*)var, to_bin->Ret, to_bin)); { result = (SAstExpr*)Alloc(sizeof(SAstExpr)); InitAstExpr(result, AstTypeId_ExprRef, ((SAst*)ast)->Pos); @@ -1537,7 +1537,7 @@ static void RebuildClass(SAstClass* ast) } do_->Expr = (SAstExpr*)assign; } - ListAdd(to_bin->Stats, do_); + ListAdd(to_bin->Stats, RebuildStat((SAstStat*)do_, to_bin->Ret, to_bin)); } } ptr2 = ptr2->Next; @@ -1549,7 +1549,7 @@ static void RebuildClass(SAstClass* ast) SAstStatRet* ret = (SAstStatRet*)Alloc(sizeof(SAstStatRet)); InitAst((SAst*)ret, AstTypeId_StatRet, ((SAst*)ast)->Pos); ret->Value = result; - ListAdd(to_bin->Stats, ret); + ListAdd(to_bin->Stats, RebuildStat((SAstStat*)ret, to_bin->Ret, to_bin)); } } // The '_fromBin' function. @@ -1578,7 +1578,7 @@ static void RebuildClass(SAstClass* ast) } var->Def = var2; } - ListAdd(from_bin->Stats, var); + ListAdd(from_bin->Stats, RebuildStat((SAstStat*)var, from_bin->Ret, from_bin)); { result = (SAstExpr*)Alloc(sizeof(SAstExpr)); InitAstExpr(result, AstTypeId_ExprRef, ((SAst*)ast)->Pos); @@ -1638,7 +1638,7 @@ static void RebuildClass(SAstClass* ast) } do_->Expr = (SAstExpr*)assign; } - ListAdd(from_bin->Stats, do_); + ListAdd(from_bin->Stats, RebuildStat((SAstStat*)do_, from_bin->Ret, from_bin)); } } ptr2 = ptr2->Next; @@ -1650,7 +1650,7 @@ static void RebuildClass(SAstClass* ast) SAstStatRet* ret = (SAstStatRet*)Alloc(sizeof(SAstStatRet)); InitAst((SAst*)ret, AstTypeId_StatRet, ((SAst*)ast)->Pos); ret->Value = result; - ListAdd(from_bin->Stats, ret); + ListAdd(from_bin->Stats, RebuildStat((SAstStat*)ret, from_bin->Ret, from_bin)); } } RebuildFunc(dtor); diff --git a/src/compiler/parse.c b/src/compiler/parse.c index d6319329..151e07cb 100644 --- a/src/compiler/parse.c +++ b/src/compiler/parse.c @@ -3647,7 +3647,7 @@ static SAstExpr* ParseExprNumber(int row, int col, Char c) int bit_size = 0; // The size for bit types. for (; ; ) { - if (c == L'#') + if (c == L'x') { if (change_base || float_type) { @@ -3655,19 +3655,14 @@ static SAstExpr* ParseExprNumber(int row, int col, Char c) ReadUntilRet(c); return NULL; } + if (len != 1 || buf[0] != L'0') { - Char* end_ptr; - errno = 0; - buf[len] = L'\0'; - base = wcstol(buf, &end_ptr, 10); - if (*end_ptr != L'\0' || errno == ERANGE || !(base == 2 || base == 8 || base == 16)) - { - Err(L"EP0019", NewPos(SrcName, row, col), base); - ReadUntilRet(c); - return NULL; - } + Err(L"EP0019", NewPos(SrcName, row, col)); + ReadUntilRet(c); + return NULL; } len = 0; + base = 16; change_base = True; } else if (c == L'.') @@ -3908,7 +3903,7 @@ static void InterpretImpl1Color(int* ptr, int str_level, const Char* str, U8* co { color[*ptr] = new_color; (*ptr)++; - } while (L'0' <= str[*ptr] && str[*ptr] <= L'9' || L'A' <= str[*ptr] && str[*ptr] <= L'F' || str[*ptr] == L'#' || str[*ptr] == L'.'); + } while (L'0' <= str[*ptr] && str[*ptr] <= L'9' || L'A' <= str[*ptr] && str[*ptr] <= L'F' || str[*ptr] == L'x' || str[*ptr] == L'.'); if (str[*ptr] == L'e') { color[*ptr] = new_color; @@ -4311,7 +4306,7 @@ static void InterpretImpl1AlignRecursion(int* ptr_buf, int* ptr_str, int str_lev Interpret1Impl1UpdateCursor(cursor_x, new_cursor_x, ptr_str, ptr_buf); InterpretImpl1Write(ptr_buf, buf, str[*ptr_str]); (*ptr_str)++; - } while (L'0' <= str[*ptr_str] && str[*ptr_str] <= L'9' || L'A' <= str[*ptr_str] && str[*ptr_str] <= L'F' || str[*ptr_str] == L'#' || str[*ptr_str] == L'.'); + } while (L'0' <= str[*ptr_str] && str[*ptr_str] <= L'9' || L'A' <= str[*ptr_str] && str[*ptr_str] <= L'F' || str[*ptr_str] == L'x' || str[*ptr_str] == L'.'); if (str[*ptr_str] == L'e') { Interpret1Impl1UpdateCursor(cursor_x, new_cursor_x, ptr_str, ptr_buf); @@ -5560,7 +5555,7 @@ static Bool GetKeywordsReadExprNumber(const Char** str, Char c) { for (; ; ) { - if (!(c == L'#' || c == L'.' || L'0' <= c && c <= L'9' || L'A' <= c && c <= L'F')) + if (!(c == L'x' || c == L'.' || L'0' <= c && c <= L'9' || L'A' <= c && c <= L'F')) break; c = GetKeywordsRead(str); if (c == L'\0') diff --git a/src/kuin_editor/common.kn b/src/kuin_editor/common.kn index a7eccffb..921dfb42 100644 --- a/src/kuin_editor/common.kn +++ b/src/kuin_editor/common.kn @@ -4,7 +4,7 @@ +const langEn: bool :: false +const untitledSrcName: []char :: "_untitled_.kn" +const untitledInternalName: []char :: "\\_untitled_" -+const colorBack: int :: 16#FFFFF5F5 ++const colorBack: int :: 0xFFFFF5F5 +var title: []char +var font: draw@Font diff --git a/src/kuin_editor/doc_ar.kn b/src/kuin_editor/doc_ar.kn index b902e683..fc96f69e 100644 --- a/src/kuin_editor/doc_ar.kn +++ b/src/kuin_editor/doc_ar.kn @@ -1,5 +1,6 @@ +class DocArBase(\doc@Doc) - **func ctor() + *func ctor() + do super(me) do me.scrollOffsetX :: 10 do me.scrollOffsetY :: 40 do me.pageX :: -me.scrollOffsetX @@ -63,8 +64,8 @@ func drawRecursion(obj: @Obj2d, pageX: int, pageY: int, hold: @Obj2d) if(hold =& obj) - do draw@rectLine((obj.absX - 3 - pageX) $ float, (obj.absY - 3 - pageY) $ float, (obj.width + 6) $ float, (obj.height + 6) $ float, 16#FF6666FF) - do draw@rectLine((obj.absX - 4 - pageX) $ float, (obj.absY - 4 - pageY) $ float, (obj.width + 8) $ float, (obj.height + 8) $ float, 16#FF6666FF) + do draw@rectLine((obj.absX - 3 - pageX) $ float, (obj.absY - 3 - pageY) $ float, (obj.width + 6) $ float, (obj.height + 6) $ float, 0xFF6666FF) + do draw@rectLine((obj.absX - 4 - pageX) $ float, (obj.absY - 4 - pageY) $ float, (obj.width + 8) $ float, (obj.height + 8) $ float, 0xFF6666FF) end if do obj.draw(pageX, pageY) do obj.children.head() @@ -626,7 +627,8 @@ end class +class Obj2d() - **func ctor() + *func ctor() + do super(me) do me.init("root", 0, 0, 800, 450) end func diff --git a/src/kuin_editor/doc_ar_wnd.kn b/src/kuin_editor/doc_ar_wnd.kn index 72cdc0f2..44e64f1e 100644 --- a/src/kuin_editor/doc_ar_wnd.kn +++ b/src/kuin_editor/doc_ar_wnd.kn @@ -1,5 +1,6 @@ +class DocArWnd(\doc_ar@DocArBase) - **func ctor() + *func ctor() + do super(me) do me.obj2dRoot :: #@Obj2dWnd end func @@ -32,7 +33,8 @@ ret null end func - **func addCtrlList(ctrlList: wnd@List) + *func addCtrlList(ctrlList: wnd@List) + do super(me, ctrlList) do ctrlList.add("button") do ctrlList.add("check") do ctrlList.add("group") @@ -48,7 +50,8 @@ end class class Obj2dWnd(\doc_ar@Obj2dRoot) - **func ctor() + *func ctor() + do super(me) do me.style :: 0 do me.layered :: false do me.noMinimize :: false @@ -62,11 +65,13 @@ class Obj2dWnd(\doc_ar@Obj2dRoot) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["style", "layered", "no_minimize", "text"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("style", me.style.toStr()) do node.setAttr("layered", me.layered.toStr()) do node.setAttr("no_minimize", me.noMinimize.toStr()) @@ -78,13 +83,14 @@ class Obj2dWnd(\doc_ar@Obj2dRoot) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFF0F0F0) - do draw@rect(x, y - 30.0, width, 30.0, 16#FFFFFFFF) - do draw@rectLine(x - 1.0, y - 31.0, width + 2.0, height + 32.0, 16#FF1883D7) + do draw@rect(x, y, width, height, 0xFFF0F0F0) + do draw@rect(x, y - 30.0, width, 30.0, 0xFFFFFFFF) + do draw@rectLine(x - 1.0, y - 31.0, width + 2.0, height + 32.0, 0xFF1883D7) do \common@fontP.draw(x + 30.0, y - 30.0 + 6.0, me.text, draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("style") do listView.setText(idx + 0, 1, style(me.style)) @@ -109,7 +115,8 @@ class Obj2dWnd(\doc_ar@Obj2dRoot) end func end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "style" do me.style :: style(value) @@ -142,24 +149,28 @@ class Obj2dWnd(\doc_ar@Obj2dRoot) end class class Obj2dWndBase(\doc_ar@Obj2d) - **func ctor() + *func ctor() + do super(me) do me.anchorX :: 0 do me.enabled :: true do me.visible :: true end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["anchor_x", "anchor_y", "enabled", "visible"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("anchor_x", me.anchorX.toStr()) do node.setAttr("anchor_y", me.anchorY.toStr()) do node.setAttr("enabled", me.enabled.toStr()) do node.setAttr("visible", me.visible.toStr()) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("anchor_x") do listView.setText(idx + 0, 1, anchor(me.anchorX)) @@ -182,7 +193,8 @@ class Obj2dWndBase(\doc_ar@Obj2d) end func end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "anchor_x" do me.anchorX :: anchor(value) @@ -213,7 +225,8 @@ class Obj2dWndBase(\doc_ar@Obj2d) end class class Obj2dBtn(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.text :: "button" end func @@ -228,11 +241,13 @@ class Obj2dBtn(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["text"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("text", me.text) end func @@ -241,18 +256,20 @@ class Obj2dBtn(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFE1E1E1) - do draw@rectLine(x, y, width, height, 16#FFADADAD) + do draw@rect(x, y, width, height, 0xFFE1E1E1) + do draw@rectLine(x, y, width, height, 0xFFADADAD) do \common@fontP.draw(lib@floor(x + (width - \common@fontP.calcWidth(me.text)) / 2.0), lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0), me.text, draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("text") do listView.setText(idx + 0, 1, me.text) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "text" do me.text :: value @@ -263,7 +280,8 @@ class Obj2dBtn(@Obj2dWndBase) end class class Obj2dChk(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.text :: "check" end func @@ -278,11 +296,13 @@ class Obj2dChk(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["text"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("text", me.text) end func @@ -291,18 +311,20 @@ class Obj2dChk(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, lib@floor(y + (height - 13.0) / 2.0), 13.0, 13.0, 16#FFFFFFFF) - do draw@rectLine(x, lib@floor(y + (height - 13.0) / 2.0), 13.0, 13.0, 16#FF333333) + do draw@rect(x, lib@floor(y + (height - 13.0) / 2.0), 13.0, 13.0, 0xFFFFFFFF) + do draw@rectLine(x, lib@floor(y + (height - 13.0) / 2.0), 13.0, 13.0, 0xFF333333) do \common@fontP.draw(x + 18.0, lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0), me.text, draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("text") do listView.setText(idx + 0, 1, me.text) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "text" do me.text :: value @@ -313,7 +335,8 @@ class Obj2dChk(@Obj2dWndBase) end class class Obj2dGroup(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.text :: "group" end func @@ -328,11 +351,13 @@ class Obj2dGroup(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["text"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("text", me.text) end func @@ -341,17 +366,19 @@ class Obj2dGroup(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rectLine(x, y + 6.0, width, height - 6.0, 16#FFDCDCDC) + do draw@rectLine(x, y + 6.0, width, height - 6.0, 0xFFDCDCDC) do \common@fontP.draw(x + 8.0, y + 0.0, me.text, draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("text") do listView.setText(idx + 0, 1, me.text) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "text" do me.text :: value @@ -362,7 +389,8 @@ class Obj2dGroup(@Obj2dWndBase) end class class Obj2dLabel(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.text :: "label" end func @@ -377,11 +405,13 @@ class Obj2dLabel(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["text"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("text", me.text) end func @@ -390,17 +420,19 @@ class Obj2dLabel(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFEEEEEE) + do draw@rect(x, y, width, height, 0xFFEEEEEE) do \common@fontP.draw(x, y, me.text, draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("text") do listView.setText(idx + 0, 1, me.text) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "text" do me.text :: value @@ -411,7 +443,8 @@ class Obj2dLabel(@Obj2dWndBase) end class class Obj2dList(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) end func +*func getName(): []char @@ -425,10 +458,12 @@ class Obj2dList(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) end func +*func draw(pageX: int, pageY: int) @@ -436,20 +471,23 @@ class Obj2dList(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFFFFFFF) - do draw@rectLine(x, y, width, height, 16#FF828790) + do draw@rect(x, y, width, height, 0xFFFFFFFF) + do draw@rectLine(x, y, width, height, 0xFF828790) do \common@fontP.draw(x + 5.0, y + 3.0, "list", draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) end func end class class Obj2dListView(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) end func +*func getName(): []char @@ -463,10 +501,12 @@ class Obj2dListView(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) end func +*func draw(pageX: int, pageY: int) @@ -474,20 +514,23 @@ class Obj2dListView(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFFFFFFF) - do draw@rectLine(x, y, width, height, 16#FF828790) + do draw@rect(x, y, width, height, 0xFFFFFFFF) + do draw@rectLine(x, y, width, height, 0xFF828790) do \common@fontP.draw(x + 5.0, y + 3.0, "list_view", draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) end func end class class Obj2dDraw(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.equalMagnification :: false end func @@ -502,11 +545,13 @@ class Obj2dDraw(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["equal_magnification"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("equal_magnification", me.equalMagnification.toStr()) end func @@ -515,16 +560,18 @@ class Obj2dDraw(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FF000000) + do draw@rect(x, y, width, height, 0xFF000000) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("equal_magnification") do listView.setText(idx + 0, 1, me.equalMagnification.toStr()) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "equal_magnification" do me.equalMagnification :: value = "true" @@ -535,7 +582,8 @@ class Obj2dDraw(@Obj2dWndBase) end class class Obj2dRadio(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.text :: "radio" end func @@ -550,11 +598,13 @@ class Obj2dRadio(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["text"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("text", me.text) end func @@ -563,18 +613,20 @@ class Obj2dRadio(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@circle(x + 6.5, y + height / 2.0, 6.5, 6.5, 16#FF333333) - do draw@circle(x + 6.5, y + height / 2.0, 5.5, 5.5, 16#FFFFFFFF) + do draw@circle(x + 6.5, y + height / 2.0, 6.5, 6.5, 0xFF333333) + do draw@circle(x + 6.5, y + height / 2.0, 5.5, 5.5, 0xFFFFFFFF) do \common@fontP.draw(x + 18.0, lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0), me.text, draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("text") do listView.setText(idx + 0, 1, me.text) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "text" do me.text :: value @@ -585,7 +637,8 @@ class Obj2dRadio(@Obj2dWndBase) end class class Obj2dEdit(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.readonly :: false end func @@ -600,11 +653,13 @@ class Obj2dEdit(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["readonly"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("readonly", me.readonly.toStr()) end func @@ -613,18 +668,20 @@ class Obj2dEdit(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFFFFFFF) - do draw@rectLine(x, y, width, height, 16#FF7A7A7A) + do draw@rect(x, y, width, height, 0xFFFFFFFF) + do draw@rectLine(x, y, width, height, 0xFF7A7A7A) do \common@fontP.draw(x + 5.0, y + 3.0, "edit", draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("readonly") do listView.setText(idx + 0, 1, me.readonly.toStr()) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "readonly" do me.readonly :: value = "true" @@ -635,7 +692,8 @@ class Obj2dEdit(@Obj2dWndBase) end class class Obj2dEditMulti(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) do me.readonly :: false end func @@ -650,11 +708,13 @@ class Obj2dEditMulti(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) do me.setProps(node, ["readonly"]) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) do node.setAttr("readonly", me.readonly.toStr()) end func @@ -663,18 +723,20 @@ class Obj2dEditMulti(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFFFFFFF) - do draw@rectLine(x, y, width, height, 16#FF7A7A7A) + do draw@rect(x, y, width, height, 0xFFFFFFFF) + do draw@rectLine(x, y, width, height, 0xFF7A7A7A) do \common@fontP.draw(x + 5.0, y + 3.0, "edit_multi", draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) var idx: int :: listView.len() do listView.add("readonly") do listView.setText(idx + 0, 1, me.readonly.toStr()) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) switch(prop) case "readonly" do me.readonly :: value = "true" @@ -685,7 +747,8 @@ class Obj2dEditMulti(@Obj2dWndBase) end class class Obj2dTree(@Obj2dWndBase) - **func ctor() + *func ctor() + do super(me) end func +*func getName(): []char @@ -698,10 +761,12 @@ class Obj2dTree(@Obj2dWndBase) do maxHeight :: lib@intMax end func - +**func load(node: xml@Node) + +*func load(node: xml@Node) + do super(me, node) end func - +**func save(node: xml@Node) + +*func save(node: xml@Node) + do super(me, node) end func +*func draw(pageX: int, pageY: int) @@ -709,14 +774,16 @@ class Obj2dTree(@Obj2dWndBase) var y: float :: (me.absY - pageY) $ float var width: float :: me.width $ float var height: float :: me.height $ float - do draw@rect(x, y, width, height, 16#FFFFFFFF) - do draw@rectLine(x, y, width, height, 16#FF828790) + do draw@rect(x, y, width, height, 0xFFFFFFFF) + do draw@rectLine(x, y, width, height, 0xFF828790) do \common@fontP.draw(x + 5.0, y + 3.0, "tree", draw@black) end func - +**func updateProp(listView: wnd@ListView, x: int, y: int) + +*func updateProp(listView: wnd@ListView, x: int, y: int) + do super(me, listView, x, y) end func - +**func setProp(prop: []char, value: []char) + +*func setProp(prop: []char, value: []char) + do super(me, prop, value) end func end class diff --git a/src/kuin_editor/doc_src.kn b/src/kuin_editor/doc_src.kn index b675d9b6..5ae78eee 100644 --- a/src/kuin_editor/doc_src.kn +++ b/src/kuin_editor/doc_src.kn @@ -25,20 +25,21 @@ var srcCharColor: []int +func init() do @srcCharColor :: #[%max $ @CharColor $ int]int - do @srcCharColor[%none $ @CharColor $ int] :: 16#FF999999 - do @srcCharColor[%identifier $ @CharColor $ int] :: 16#FF009BEA - do @srcCharColor[%global $ @CharColor $ int] :: 16#FFCC00F6 - do @srcCharColor[%reserved $ @CharColor $ int] :: 16#FF1400F6 - do @srcCharColor[%num $ @CharColor $ int] :: 16#FFEA0062 - do @srcCharColor[%str $ @CharColor $ int] :: 16#FFEA0062 - do @srcCharColor[%char_ $ @CharColor $ int] :: 16#FFEA0062 - do @srcCharColor[%lineComment $ @CharColor $ int] :: 16#FF1EB000 - do @srcCharColor[%comment $ @CharColor $ int] :: 16#FF1EB000 - do @srcCharColor[%symbol $ @CharColor $ int] :: 16#FF666666 + do @srcCharColor[%none $ @CharColor $ int] :: 0xFF999999 + do @srcCharColor[%identifier $ @CharColor $ int] :: 0xFF009BEA + do @srcCharColor[%global $ @CharColor $ int] :: 0xFFCC00F6 + do @srcCharColor[%reserved $ @CharColor $ int] :: 0xFF1400F6 + do @srcCharColor[%num $ @CharColor $ int] :: 0xFFEA0062 + do @srcCharColor[%str $ @CharColor $ int] :: 0xFFEA0062 + do @srcCharColor[%char_ $ @CharColor $ int] :: 0xFFEA0062 + do @srcCharColor[%lineComment $ @CharColor $ int] :: 0xFF1EB000 + do @srcCharColor[%comment $ @CharColor $ int] :: 0xFF1EB000 + do @srcCharColor[%symbol $ @CharColor $ int] :: 0xFF666666 end func +class DocSrc(\doc@Doc) - **func ctor() + *func ctor() + do super(me) do me.src :: #Src do me.src.src :: null do me.src.color :: null @@ -123,7 +124,7 @@ end func var left: int :: me.lineNumWidth - me.pageX * \common@cellWidth var x: int :: 0 for j(0, ^str) - assert j = ^str | str[j] <> 16#01 $ char & str[j] <> '\n' + assert j = ^str | str[j] <> 0x01 $ char & str[j] <> '\n' var x2: int :: left + x * \common@cellWidth if(x2 >= width) break j @@ -159,11 +160,11 @@ end func if(inArea) do draw@rect(textX, textY, (\common@cellWidth * (charWidth <= 0 ?(1, charWidth))) $ float, \common@cellHeight $ float, colorAreaBack) do color :: draw@white - elif(me.src.color[me.pageY + i][j].and(16#80b8) <> 0 $ @CharColor $ bit8) + elif(me.src.color[me.pageY + i][j].and(0x80b8) <> 0 $ @CharColor $ bit8) do draw@rect(textX, textY, (\common@cellWidth * (charWidth <= 0 ?(1, charWidth))) $ float, \common@cellHeight $ float, colorErrBack) do color :: draw@white else - do color :: @srcCharColor[me.src.color[me.pageY + i][j].and(16#7Fb8) $ int] + do color :: @srcCharColor[me.src.color[me.pageY + i][j].and(0x7Fb8) $ int] end if switch(str[j]) case '\t' @@ -250,11 +251,11 @@ end func end if end if if(^me.src.src[me.cursorY] > 0) - var color: bit8 :: me.src.color[me.areaY][me.areaX].and(16#7Fb8) - while(me.areaX > 0 & me.src.color[me.areaY][me.areaX - 1].and(16#7Fb8) = color) + var color: bit8 :: me.src.color[me.areaY][me.areaX].and(0x7Fb8) + while(me.areaX > 0 & me.src.color[me.areaY][me.areaX - 1].and(0x7Fb8) = color) do me.areaX :- 1 end while - while(me.cursorX < ^me.src.src[me.cursorY] & me.src.color[me.cursorY][me.cursorX].and(16#7Fb8) = color) + while(me.cursorX < ^me.src.src[me.cursorY] & me.src.color[me.cursorY][me.cursorX].and(0x7Fb8) = color) do me.cursorX :+ 1 end while end if @@ -822,13 +823,13 @@ end func end if end func - const colorLineNum: int :: 16#FFFF7F7F - const colorAreaBack: int :: 16#FF808080 - const colorErrBack: int :: 16#FFFF3333 + const colorLineNum: int :: 0xFFFF7F7F + const colorAreaBack: int :: 0xFF808080 + const colorErrBack: int :: 0xFFFF3333 enum LineFlag - none :: 16#00 - nextLine :: 16#01 + none :: 0x00 + nextLine :: 0x01 end enum class Src() @@ -883,11 +884,11 @@ end func func charWidth(c: char, x: int): int if(c = '\t') ret 4 - x % 4 - elif(c $ int <= 16#1F) + elif(c $ int <= 0x1F) ret 0 - elif(c $ int <= 16#7E) + elif(c $ int <= 0x7E) ret 1 - elif(c $ int <= 16#A0) + elif(c $ int <= 0xA0) ret 0 end if ret 2 @@ -1428,7 +1429,7 @@ end func ret me.src.src[y].sub(first, last - first).trim() func keyword(color: bit8): bool - do color :: color.and(16#7Fb8) + do color :: color.and(0x7Fb8) ret color = %identifier $ @CharColor $ bit8 | color = %global $ @CharColor $ bit8 | color = %reserved $ @CharColor $ bit8 end func end func diff --git a/src/kuin_editor/form.kn b/src/kuin_editor/form.kn index d4472015..1deeb0e0 100644 --- a/src/kuin_editor/form.kn +++ b/src/kuin_editor/form.kn @@ -74,41 +74,41 @@ var drag: bool do @listFile.onSel :: @listFileOnSel do @menuMain :: wnd@makeMenu() do @popupMainFile :: wnd@makePopup() - do @popupMainFile.add(16#0001, \common@langEn ?("&New\tCtrl+N", "新規作成(&N)\tCtrl+N")) - do @popupMainFile.add(16#0002, \common@langEn ?("&Load...\tCtrl+O", "開く(&O)\tCtrl+O")) + do @popupMainFile.add(0x0001, \common@langEn ?("&New\tCtrl+N", "新規作成(&N)\tCtrl+N")) + do @popupMainFile.add(0x0002, \common@langEn ?("&Load...\tCtrl+O", "開く(&O)\tCtrl+O")) do @popupMainFile.addLine() - do @popupMainFile.add(16#0003, \common@langEn ?("&Save All\tCtrl+S", "すべて保存(&S)\tCtrl+S")) - do @popupMainFile.add(16#0004, \common@langEn ?("Save &As...\tCtrl+Shift+S", "名前を付けて保存(&A)\tCtrl+Shift+S")) + do @popupMainFile.add(0x0003, \common@langEn ?("&Save All\tCtrl+S", "すべて保存(&S)\tCtrl+S")) + do @popupMainFile.add(0x0004, \common@langEn ?("Save &As...\tCtrl+Shift+S", "名前を付けて保存(&A)\tCtrl+Shift+S")) do @popupMainFile.addLine() - do @popupMainFile.add(16#0005, \common@langEn ?("E&xit\tCtrl+Q", "終了(&E)\tCtrl+Q")) + do @popupMainFile.add(0x0005, \common@langEn ?("E&xit\tCtrl+Q", "終了(&E)\tCtrl+Q")) do @menuMain.addPopup(\common@langEn ?("&File", "ファイル(&F)"), @popupMainFile) do @popupMainEdit :: wnd@makePopup() - do @popupMainEdit.add(16#0030, \common@langEn ?("Add Ne&w File\tCtrl+Shift+A", "新しいファイルを追加(&W)\tCtrl+Shift+A")) - do @popupMainEdit.add(16#0031, \common@langEn ?("Add Existin&g File", "既存のファイルを追加(&G)")) + do @popupMainEdit.add(0x0030, \common@langEn ?("Add Ne&w File\tCtrl+Shift+A", "新しいファイルを追加(&W)\tCtrl+Shift+A")) + do @popupMainEdit.add(0x0031, \common@langEn ?("Add Existin&g File", "既存のファイルを追加(&G)")) do @popupMainEdit.addLine() - do @popupMainEdit.add(16#0032, \common@langEn ?("&Undo\tCtrl+Z", "元に戻す(&U)\tCtrl+Z")) - do @popupMainEdit.add(16#0033, \common@langEn ?("&Redo\tCtrl+Shift+Z, Ctrl+Y", "やり直し(&R)\tCtrl+Shift+Z, Ctrl+Y")) + do @popupMainEdit.add(0x0032, \common@langEn ?("&Undo\tCtrl+Z", "元に戻す(&U)\tCtrl+Z")) + do @popupMainEdit.add(0x0033, \common@langEn ?("&Redo\tCtrl+Shift+Z, Ctrl+Y", "やり直し(&R)\tCtrl+Shift+Z, Ctrl+Y")) do @popupMainEdit.addLine() - do @popupMainEdit.add(16#0034, \common@langEn ?("Cu&t\tCtrl+X", "切り取り(&T)\tCtrl+X")) - do @popupMainEdit.add(16#0035, \common@langEn ?("&Copy\tCtrl+C", "コピー(&C)\tCtrl+C")) - do @popupMainEdit.add(16#0036, \common@langEn ?("&Paste\tCtrl+V", "貼り付け(&P)\tCtrl+V")) - do @popupMainEdit.add(16#0037, \common@langEn ?("&Delete\tDel", "削除(&D)\tDel")) - do @popupMainEdit.add(16#0038, \common@langEn ?("Select &All\tCtrl+A", "すべて選択(&A)\tCtrl+A")) + do @popupMainEdit.add(0x0034, \common@langEn ?("Cu&t\tCtrl+X", "切り取り(&T)\tCtrl+X")) + do @popupMainEdit.add(0x0035, \common@langEn ?("&Copy\tCtrl+C", "コピー(&C)\tCtrl+C")) + do @popupMainEdit.add(0x0036, \common@langEn ?("&Paste\tCtrl+V", "貼り付け(&P)\tCtrl+V")) + do @popupMainEdit.add(0x0037, \common@langEn ?("&Delete\tDel", "削除(&D)\tDel")) + do @popupMainEdit.add(0x0038, \common@langEn ?("Select &All\tCtrl+A", "すべて選択(&A)\tCtrl+A")) do @popupMainEdit.addLine() - do @popupMainEdit.add(16#0039, \common@langEn ?("&Find\tCtrl+F", "検索(&F)\tCtrl+F")) - do @popupMainEdit.add(16#003A, \common@langEn ?("&Replace\tCtrl+H", "置換(&R)\tCtrl+H")) - do @popupMainEdit.add(16#003B, \common@langEn ?("Find Pre&vious\tShift+F3", "前を検索(&V)\tShift+F3")) - do @popupMainEdit.add(16#003C, \common@langEn ?("Find &Next\tF3", "次を検索(&N)\tF3")) + do @popupMainEdit.add(0x0039, \common@langEn ?("&Find\tCtrl+F", "検索(&F)\tCtrl+F")) + do @popupMainEdit.add(0x003A, \common@langEn ?("&Replace\tCtrl+H", "置換(&R)\tCtrl+H")) + do @popupMainEdit.add(0x003B, \common@langEn ?("Find Pre&vious\tShift+F3", "前を検索(&V)\tShift+F3")) + do @popupMainEdit.add(0x003C, \common@langEn ?("Find &Next\tF3", "次を検索(&N)\tF3")) do @menuMain.addPopup(\common@langEn ?("&Edit", "編集(&E)"), @popupMainEdit) do @popupMainBuild :: wnd@makePopup() - do @popupMainBuild.add(16#0020, \common@langEn ?("&Compile && Run\tF5", "コンパイル&実行(&C)\tF5")) + do @popupMainBuild.add(0x0020, \common@langEn ?("&Compile && Run\tF5", "コンパイル&実行(&C)\tF5")) do @popupMainBuild.addLine() - do @popupMainBuild.add(16#0021, \common@langEn ?("&Release Build...\tCtrl+Shift+B", "リリースビルド(&R)...\tCtrl+Shift+B")) + do @popupMainBuild.add(0x0021, \common@langEn ?("&Release Build...\tCtrl+Shift+B", "リリースビルド(&R)...\tCtrl+Shift+B")) do @menuMain.addPopup(\common@langEn ?("&Build", "ビルド(&B)"), @popupMainBuild) do @popupMainHelp :: wnd@makePopup() - do @popupMainHelp.add(16#0010, \common@langEn ?("&View Help\tF1", "ヘルプの表示(&V)\tF1")) + do @popupMainHelp.add(0x0010, \common@langEn ?("&View Help\tF1", "ヘルプの表示(&V)\tF1")) do @popupMainHelp.addLine() - do @popupMainHelp.add(16#0011, \common@langEn ?("&About Kuin...", "Kuinについて(&A)...")) + do @popupMainHelp.add(0x0011, \common@langEn ?("&About Kuin...", "Kuinについて(&A)...")) do @menuMain.addPopup(\common@langEn ?("&Help", "ヘルプ(&H)"), @popupMainHelp) do @wndMain.setMenu(@menuMain) @@ -151,22 +151,22 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool do \find@wndFind.close() ret true case %f3 - do @wndMainOnPushMenu(@wndMain, 16#003C) + do @wndMainOnPushMenu(@wndMain, 0x003C) ret true end switch case %shift switch(key) case %f3 - do @wndMainOnPushMenu(@wndMain, 16#003B) + do @wndMainOnPushMenu(@wndMain, 0x003B) ret true end switch case %ctrl switch(key) case %f - do @wndMainOnPushMenu(@wndMain, 16#0039) + do @wndMainOnPushMenu(@wndMain, 0x0039) ret true case %h - do @wndMainOnPushMenu(@wndMain, 16#003A) + do @wndMainOnPushMenu(@wndMain, 0x003A) ret true end switch end switch @@ -180,7 +180,7 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool switch(key) case %del if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0037) + do @wndMainOnPushMenu(@wndMain, 0x0037) ret true end if case %esc @@ -192,13 +192,13 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool ret true end if case %f1 - do @wndMainOnPushMenu(@wndMain, 16#0010) + do @wndMainOnPushMenu(@wndMain, 0x0010) ret true case %f3 - do @wndMainOnPushMenu(@wndMain, 16#003C) + do @wndMainOnPushMenu(@wndMain, 0x003C) ret true case %f5 - do @wndMainOnPushMenu(@wndMain, 16#0020) + do @wndMainOnPushMenu(@wndMain, 0x0020) ret true case %f12 var definitionPos: \src@Pos :: \completion@getDefinitionPos() @@ -209,73 +209,73 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool case %shift switch(key) case %f3 - do @wndMainOnPushMenu(@wndMain, 16#003B) + do @wndMainOnPushMenu(@wndMain, 0x003B) ret true end switch case %ctrl switch(key) case %a if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0038) + do @wndMainOnPushMenu(@wndMain, 0x0038) ret true end if case %c if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0035) + do @wndMainOnPushMenu(@wndMain, 0x0035) ret true end if case %f - do @wndMainOnPushMenu(@wndMain, 16#0039) + do @wndMainOnPushMenu(@wndMain, 0x0039) ret true case %h - do @wndMainOnPushMenu(@wndMain, 16#003A) + do @wndMainOnPushMenu(@wndMain, 0x003A) ret true case %n - do @wndMainOnPushMenu(@wndMain, 16#0001) + do @wndMainOnPushMenu(@wndMain, 0x0001) ret true case %o - do @wndMainOnPushMenu(@wndMain, 16#0002) + do @wndMainOnPushMenu(@wndMain, 0x0002) ret true case %s - do @wndMainOnPushMenu(@wndMain, 16#0003) + do @wndMainOnPushMenu(@wndMain, 0x0003) ret true case %q - do @wndMainOnPushMenu(@wndMain, 16#0005) + do @wndMainOnPushMenu(@wndMain, 0x0005) ret true case %v if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0036) + do @wndMainOnPushMenu(@wndMain, 0x0036) ret true end if case %x if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0034) + do @wndMainOnPushMenu(@wndMain, 0x0034) ret true end if case %y if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0033) + do @wndMainOnPushMenu(@wndMain, 0x0033) ret true end if case %z if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0032) + do @wndMainOnPushMenu(@wndMain, 0x0032) ret true end if end switch case (%shift $ wnd@ShiftCtrl).or(%ctrl) switch(key) case %a - do @wndMainOnPushMenu(@wndMain, 16#0030) + do @wndMainOnPushMenu(@wndMain, 0x0030) case %b - do @wndMainOnPushMenu(@wndMain, 16#0021) + do @wndMainOnPushMenu(@wndMain, 0x0021) ret true case %s - do @wndMainOnPushMenu(@wndMain, 16#0004) + do @wndMainOnPushMenu(@wndMain, 0x0004) ret true case %z if(!editFocused) - do @wndMainOnPushMenu(@wndMain, 16#0033) + do @wndMainOnPushMenu(@wndMain, 0x0033) ret true end if end switch @@ -312,7 +312,7 @@ end func func wndMainOnPushMenu(wnd: wnd@WndBase, id: int) switch(id) - case 16#0001 + case 0x0001 if(@lockingEditor) do @showMsgRunning() ret @@ -320,7 +320,7 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int) if (\src@chkChanged()) do \src@newMainSrc() end if - case 16#0002 + case 0x0002 if(@lockingEditor) do @showMsgRunning() ret @@ -331,15 +331,15 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int) do \src@openMainSrc(file) end if end if - case 16#0003 + case 0x0003 do \src@saveAll() - case 16#0004 + case 0x0004 do \src@saveMainSrc() - case 16#0005 + case 0x0005 do @wndMain.close() - case 16#0010 + case 0x0010 do task@open("http://kuina.ch/kuin") - case 16#0011 + case 0x0011 block var major: int var minor: int @@ -347,51 +347,51 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int) do \dll@version(&major, &minor, µ) do wnd@msgBox(@wndMain, "Kuin Programming Language\nVersion \{major}.\{minor}.\{micro}\n(C)Kuina-chan", \common@title, %info, %ok) end block - case 16#0020 + case 0x0020 if(@lockingEditor) do @showMsgRunning() ret end if do @btnCompileOnPush(@btnCompile) - case 16#0021 + case 0x0021 if(@lockingEditor) do @showMsgRunning() ret end if do @btnRlsOnPush(@btnRls) - case 16#0030 + case 0x0030 if(@lockingEditor) do @showMsgRunning() ret end if do \add_file@addNewFile() - case 16#0031 + case 0x0031 if(@lockingEditor) do @showMsgRunning() ret end if do \add_file@addExistingFile() - case 16#0032 + case 0x0032 do \src@curDoc.cmdUndo() - case 16#0033 + case 0x0033 do \src@curDoc.cmdRedo() - case 16#0034 + case 0x0034 do \src@curDoc.cmdCut() - case 16#0035 + case 0x0035 do \src@curDoc.cmdCopy() - case 16#0036 + case 0x0036 do \src@curDoc.cmdPaste() - case 16#0037 + case 0x0037 do \src@curDoc.cmdDel() - case 16#0038 + case 0x0038 do \src@curDoc.cmdSelAll() - case 16#0039 + case 0x0039 do \find@show(false) - case 16#003A + case 0x003A do \find@show(true) - case 16#003B + case 0x003B do \find@findPrev() - case 16#003C + case 0x003C do \find@findNext() end switch end func diff --git a/src/kuin_editor/src.kn b/src/kuin_editor/src.kn index 3c4f38f0..4eb82a18 100644 --- a/src/kuin_editor/src.kn +++ b/src/kuin_editor/src.kn @@ -411,8 +411,8 @@ end func var y: int :: pos.row - 1 var color: bit8 if(moveWordTop(doc2.src.src, doc2.src.color, &x, &y, &color)) - while(x < ^doc2.src.color[y] & doc2.src.color[y][x].and(16#7Fb8) = color) - do doc2.src.color[y][x] :: doc2.src.color[y][x].or(16#80b8) + while(x < ^doc2.src.color[y] & doc2.src.color[y][x].and(0x7Fb8) = color) + do doc2.src.color[y][x] :: doc2.src.color[y][x].or(0x80b8) do x :+ 1 end while end if @@ -425,7 +425,7 @@ end func elif(^srcColor <= y) do y :: ^srcColor - 1 end if - if(1 <= x & x < ^srcColor[y] & (src[y][x] = ' ' | src[y][x] = '\t' | srcColor[y][x].and(16#7Fb8) = %comment $ \doc_src@CharColor $ bit8 | srcColor[y][x].and(16#7Fb8) = %symbol $ \doc_src@CharColor $ bit8)) + if(1 <= x & x < ^srcColor[y] & (src[y][x] = ' ' | src[y][x] = '\t' | srcColor[y][x].and(0x7Fb8) = %comment $ \doc_src@CharColor $ bit8 | srcColor[y][x].and(0x7Fb8) = %symbol $ \doc_src@CharColor $ bit8)) do x :- 1 end if if(x < 0) @@ -434,8 +434,8 @@ end func do x :: ^srcColor[y] - 1 end if if(^srcColor[y] <> 0) - do color :: srcColor[y][x].and(16#7Fb8) - while(x >= 1 & srcColor[y][x - 1].and(16#7Fb8) = color) + do color :: srcColor[y][x].and(0x7Fb8) + while(x >= 1 & srcColor[y][x - 1].and(0x7Fb8) = color) do x :- 1 end while ret true diff --git a/test/kn/test0000.kn b/test/kn/test0000.kn index 24e80222..504cd0c9 100644 --- a/test/kn/test0000.kn +++ b/test/kn/test0000.kn @@ -68,9 +68,9 @@ func main() var b: bit32 :: (n + n) / n - n * n + n + n + n + n + n + n + n + n + n + n + (+n) + (-n) {23} do cui@print(b.toStr() ~ ", " ~ (b % n).toStr()) - var c1: bit32 :: 16#FFFFFFFFb32 + 2b32 + var c1: bit32 :: 0xFFFFFFFFb32 + 2b32 var c2: bit32 :: -1b32 - var d1: bit32 :: 16#FFFFFFFFb32 + var d1: bit32 :: 0xFFFFFFFFb32 var d2: bit32 :: 1b32 do d1 :+ 2b32 do d2 :: -d2 @@ -85,9 +85,9 @@ func main() var b: bit64 :: (n + n) / n - n * n + n + n + n + n + n + n + n + n + n + n + (+n) + (-n) {23} do cui@print(b.toStr() ~ ", " ~ (b % n).toStr()) - var c1: bit64 :: 16#FFFFFFFFFFFFFFFFb64 + 2b64 + var c1: bit64 :: 0xFFFFFFFFFFFFFFFFb64 + 2b64 var c2: bit64 :: -1b64 - var d1: bit64 :: 16#FFFFFFFFFFFFFFFFb64 + var d1: bit64 :: 0xFFFFFFFFFFFFFFFFb64 var d2: bit64 :: 1b64 do d1 :+ 2b64 do d2 :: -d2 diff --git a/test/kn/test0001.kn b/test/kn/test0001.kn index 93d8c47d..19fc431e 100644 --- a/test/kn/test0001.kn +++ b/test/kn/test0001.kn @@ -29,58 +29,58 @@ func main() end block block - do cui@print((16#79b8 = 16#81b8).toStr() ~ ", " ~ (16#79b8 <> 16#81b8).toStr() ~ ", " ~ (16#79b8 < 16#81b8).toStr() ~ ", " ~ (16#79b8 <= 16#81b8).toStr() ~ ", " ~ (16#79b8 > 16#81b8).toStr() ~ ", " ~ (16#79b8 >= 16#81b8).toStr()) + do cui@print((0x79b8 = 0x81b8).toStr() ~ ", " ~ (0x79b8 <> 0x81b8).toStr() ~ ", " ~ (0x79b8 < 0x81b8).toStr() ~ ", " ~ (0x79b8 <= 0x81b8).toStr() ~ ", " ~ (0x79b8 > 0x81b8).toStr() ~ ", " ~ (0x79b8 >= 0x81b8).toStr()) - var a: bit8 :: 16#79b8 - var b: bit8 :: 16#81b8 + var a: bit8 :: 0x79b8 + var b: bit8 :: 0x81b8 do cui@print((a = b).toStr() ~ ", " ~ (a <> b).toStr() ~ ", " ~ (a < b).toStr() ~ ", " ~ (a <= b).toStr() ~ ", " ~ (a > b).toStr() ~ ", " ~ (a >= b).toStr()) - do cui@print((16#80b8 = 16#80b8).toStr() ~ ", " ~ (16#80b8 <> 16#80b8).toStr() ~ ", " ~ (16#80b8 < 16#80b8).toStr() ~ ", " ~ (16#80b8 <= 16#80b8).toStr() ~ ", " ~ (16#80b8 > 16#80b8).toStr() ~ ", " ~ (16#80b8 >= 16#80b8).toStr()) + do cui@print((0x80b8 = 0x80b8).toStr() ~ ", " ~ (0x80b8 <> 0x80b8).toStr() ~ ", " ~ (0x80b8 < 0x80b8).toStr() ~ ", " ~ (0x80b8 <= 0x80b8).toStr() ~ ", " ~ (0x80b8 > 0x80b8).toStr() ~ ", " ~ (0x80b8 >= 0x80b8).toStr()) - var c: bit8 :: 16#80b8 - var d: bit8 :: 16#80b8 + var c: bit8 :: 0x80b8 + var d: bit8 :: 0x80b8 do cui@print((c = d).toStr() ~ ", " ~ (c <> d).toStr() ~ ", " ~ (c < d).toStr() ~ ", " ~ (c <= d).toStr() ~ ", " ~ (c > d).toStr() ~ ", " ~ (c >= d).toStr()) end block block - do cui@print((16#7900b16 = 16#8100b16).toStr() ~ ", " ~ (16#7900b16 <> 16#8100b16).toStr() ~ ", " ~ (16#7900b16 < 16#8100b16).toStr() ~ ", " ~ (16#7900b16 <= 16#8100b16).toStr() ~ ", " ~ (16#7900b16 > 16#8100b16).toStr() ~ ", " ~ (16#7900b16 >= 16#8100b16).toStr()) + do cui@print((0x7900b16 = 0x8100b16).toStr() ~ ", " ~ (0x7900b16 <> 0x8100b16).toStr() ~ ", " ~ (0x7900b16 < 0x8100b16).toStr() ~ ", " ~ (0x7900b16 <= 0x8100b16).toStr() ~ ", " ~ (0x7900b16 > 0x8100b16).toStr() ~ ", " ~ (0x7900b16 >= 0x8100b16).toStr()) - var a: bit16 :: 16#7900b16 - var b: bit16 :: 16#8100b16 + var a: bit16 :: 0x7900b16 + var b: bit16 :: 0x8100b16 do cui@print((a = b).toStr() ~ ", " ~ (a <> b).toStr() ~ ", " ~ (a < b).toStr() ~ ", " ~ (a <= b).toStr() ~ ", " ~ (a > b).toStr() ~ ", " ~ (a >= b).toStr()) - do cui@print((16#8000b16 = 16#8000b16).toStr() ~ ", " ~ (16#8000b16 <> 16#8000b16).toStr() ~ ", " ~ (16#8000b16 < 16#8000b16).toStr() ~ ", " ~ (16#8000b16 <= 16#8000b16).toStr() ~ ", " ~ (16#8000b16 > 16#8000b16).toStr() ~ ", " ~ (16#8000b16 >= 16#8000b16).toStr()) + do cui@print((0x8000b16 = 0x8000b16).toStr() ~ ", " ~ (0x8000b16 <> 0x8000b16).toStr() ~ ", " ~ (0x8000b16 < 0x8000b16).toStr() ~ ", " ~ (0x8000b16 <= 0x8000b16).toStr() ~ ", " ~ (0x8000b16 > 0x8000b16).toStr() ~ ", " ~ (0x8000b16 >= 0x8000b16).toStr()) - var c: bit16 :: 16#8000b16 - var d: bit16 :: 16#8000b16 + var c: bit16 :: 0x8000b16 + var d: bit16 :: 0x8000b16 do cui@print((c = d).toStr() ~ ", " ~ (c <> d).toStr() ~ ", " ~ (c < d).toStr() ~ ", " ~ (c <= d).toStr() ~ ", " ~ (c > d).toStr() ~ ", " ~ (c >= d).toStr()) end block block - do cui@print((16#79000000b32 = 16#81000000b32).toStr() ~ ", " ~ (16#79000000b32 <> 16#81000000b32).toStr() ~ ", " ~ (16#79000000b32 < 16#81000000b32).toStr() ~ ", " ~ (16#79000000b32 <= 16#81000000b32).toStr() ~ ", " ~ (16#79000000b32 > 16#81000000b32).toStr() ~ ", " ~ (16#79000000b32 >= 16#81000000b32).toStr()) + do cui@print((0x79000000b32 = 0x81000000b32).toStr() ~ ", " ~ (0x79000000b32 <> 0x81000000b32).toStr() ~ ", " ~ (0x79000000b32 < 0x81000000b32).toStr() ~ ", " ~ (0x79000000b32 <= 0x81000000b32).toStr() ~ ", " ~ (0x79000000b32 > 0x81000000b32).toStr() ~ ", " ~ (0x79000000b32 >= 0x81000000b32).toStr()) - var a: bit32 :: 16#79000000b32 - var b: bit32 :: 16#81000000b32 + var a: bit32 :: 0x79000000b32 + var b: bit32 :: 0x81000000b32 do cui@print((a = b).toStr() ~ ", " ~ (a <> b).toStr() ~ ", " ~ (a < b).toStr() ~ ", " ~ (a <= b).toStr() ~ ", " ~ (a > b).toStr() ~ ", " ~ (a >= b).toStr()) - do cui@print((16#80000000b32 = 16#80000000b32).toStr() ~ ", " ~ (16#80000000b32 <> 16#80000000b32).toStr() ~ ", " ~ (16#80000000b32 < 16#80000000b32).toStr() ~ ", " ~ (16#80000000b32 <= 16#80000000b32).toStr() ~ ", " ~ (16#80000000b32 > 16#80000000b32).toStr() ~ ", " ~ (16#80000000b32 >= 16#80000000b32).toStr()) + do cui@print((0x80000000b32 = 0x80000000b32).toStr() ~ ", " ~ (0x80000000b32 <> 0x80000000b32).toStr() ~ ", " ~ (0x80000000b32 < 0x80000000b32).toStr() ~ ", " ~ (0x80000000b32 <= 0x80000000b32).toStr() ~ ", " ~ (0x80000000b32 > 0x80000000b32).toStr() ~ ", " ~ (0x80000000b32 >= 0x80000000b32).toStr()) - var c: bit32 :: 16#80000000b32 - var d: bit32 :: 16#80000000b32 + var c: bit32 :: 0x80000000b32 + var d: bit32 :: 0x80000000b32 do cui@print((c = d).toStr() ~ ", " ~ (c <> d).toStr() ~ ", " ~ (c < d).toStr() ~ ", " ~ (c <= d).toStr() ~ ", " ~ (c > d).toStr() ~ ", " ~ (c >= d).toStr()) end block block - do cui@print((16#7900000000000000b64 = 16#8100000000000000b64).toStr() ~ ", " ~ (16#7900000000000000b64 <> 16#8100000000000000b64).toStr() ~ ", " ~ (16#7900000000000000b64 < 16#8100000000000000b64).toStr() ~ ", " ~ (16#7900000000000000b64 <= 16#8100000000000000b64).toStr() ~ ", " ~ (16#7900000000000000b64 > 16#8100000000000000b64).toStr() ~ ", " ~ (16#7900000000000000b64 >= 16#8100000000000000b64).toStr()) + do cui@print((0x7900000000000000b64 = 0x8100000000000000b64).toStr() ~ ", " ~ (0x7900000000000000b64 <> 0x8100000000000000b64).toStr() ~ ", " ~ (0x7900000000000000b64 < 0x8100000000000000b64).toStr() ~ ", " ~ (0x7900000000000000b64 <= 0x8100000000000000b64).toStr() ~ ", " ~ (0x7900000000000000b64 > 0x8100000000000000b64).toStr() ~ ", " ~ (0x7900000000000000b64 >= 0x8100000000000000b64).toStr()) - var a: bit64 :: 16#7900000000000000b64 - var b: bit64 :: 16#8100000000000000b64 + var a: bit64 :: 0x7900000000000000b64 + var b: bit64 :: 0x8100000000000000b64 do cui@print((a = b).toStr() ~ ", " ~ (a <> b).toStr() ~ ", " ~ (a < b).toStr() ~ ", " ~ (a <= b).toStr() ~ ", " ~ (a > b).toStr() ~ ", " ~ (a >= b).toStr()) - do cui@print((16#8000000000000000b64 = 16#8000000000000000b64).toStr() ~ ", " ~ (16#8000000000000000b64 <> 16#8000000000000000b64).toStr() ~ ", " ~ (16#8000000000000000b64 < 16#8000000000000000b64).toStr() ~ ", " ~ (16#8000000000000000b64 <= 16#8000000000000000b64).toStr() ~ ", " ~ (16#8000000000000000b64 > 16#8000000000000000b64).toStr() ~ ", " ~ (16#8000000000000000b64 >= 16#8000000000000000b64).toStr()) + do cui@print((0x8000000000000000b64 = 0x8000000000000000b64).toStr() ~ ", " ~ (0x8000000000000000b64 <> 0x8000000000000000b64).toStr() ~ ", " ~ (0x8000000000000000b64 < 0x8000000000000000b64).toStr() ~ ", " ~ (0x8000000000000000b64 <= 0x8000000000000000b64).toStr() ~ ", " ~ (0x8000000000000000b64 > 0x8000000000000000b64).toStr() ~ ", " ~ (0x8000000000000000b64 >= 0x8000000000000000b64).toStr()) - var c: bit64 :: 16#8000000000000000b64 - var d: bit64 :: 16#8000000000000000b64 + var c: bit64 :: 0x8000000000000000b64 + var d: bit64 :: 0x8000000000000000b64 do cui@print((c = d).toStr() ~ ", " ~ (c <> d).toStr() ~ ", " ~ (c < d).toStr() ~ ", " ~ (c <= d).toStr() ~ ", " ~ (c > d).toStr() ~ ", " ~ (c >= d).toStr()) end block diff --git a/test/kn/test0005.kn b/test/kn/test0005.kn index 660a5a3c..e2a5d7bf 100644 --- a/test/kn/test0005.kn +++ b/test/kn/test0005.kn @@ -49,13 +49,13 @@ func main() do cui@print((n $ int).toStr() ~ ", " ~ (n = %f).toStr() ~ ", " ~ (n <> %f).toStr() ~ ", " ~ (n < %e).toStr() ~ ", " ~ (n > %e).toStr()) do n :: 1234 $ A do cui@print((n $ int).toStr()) - do n :: 16#FFb8 $ A + do n :: 0xFFb8 $ A do cui@print((n $ int).toStr()) - do n :: 16#FFb16 $ A + do n :: 0xFFb16 $ A do cui@print((n $ int).toStr()) - do n :: 16#FFb32 $ A + do n :: 0xFFb32 $ A do cui@print((n $ int).toStr()) - do n :: 16#FFb64 $ A + do n :: 0xFFb64 $ A do cui@print((n $ int).toStr()) end block end for diff --git a/test/kn/test0009.kn b/test/kn/test0009.kn index 1590bd51..fdb91b63 100644 --- a/test/kn/test0009.kn +++ b/test/kn/test0009.kn @@ -54,8 +54,8 @@ func main() end block block - var n: bit8 :: 16#F6b8 - var m: bit8 :: 16#0Ab8 + var n: bit8 :: 0xF6b8 + var m: bit8 :: 0x0Ab8 do cui@print(n.or(m).toStr()) do cui@print(n.and(m).toStr()) do cui@print(n.xor(m).toStr()) @@ -66,8 +66,8 @@ func main() end block block - var n: bit16 :: 16#F6F6b16 - var m: bit16 :: 16#0A0Ab16 + var n: bit16 :: 0xF6F6b16 + var m: bit16 :: 0x0A0Ab16 do cui@print(n.or(m).toStr()) do cui@print(n.and(m).toStr()) do cui@print(n.xor(m).toStr()) @@ -78,8 +78,8 @@ func main() end block block - var n: bit32 :: 16#F6F6F6F6b32 - var m: bit32 :: 16#0A0A0A0Ab32 + var n: bit32 :: 0xF6F6F6F6b32 + var m: bit32 :: 0x0A0A0A0Ab32 do cui@print(n.or(m).toStr()) do cui@print(n.and(m).toStr()) do cui@print(n.xor(m).toStr()) @@ -90,8 +90,8 @@ func main() end block block - var n: bit64 :: 16#F6F6F6F6F6F6F6F6b64 - var m: bit64 :: 16#0A0A0A0A0A0A0A0Ab64 + var n: bit64 :: 0xF6F6F6F6F6F6F6F6b64 + var m: bit64 :: 0x0A0A0A0A0A0A0A0Ab64 do cui@print(n.or(m).toStr()) do cui@print(n.and(m).toStr()) do cui@print(n.xor(m).toStr()) diff --git a/test/kn/test0012.kn b/test/kn/test0012.kn index 127e3e81..a265e6b4 100644 --- a/test/kn/test0012.kn +++ b/test/kn/test0012.kn @@ -46,7 +46,7 @@ func main() block - var n: bit8 :: 16#12b8 + var n: bit8 :: 0x12b8 var m: bit8 var bin: []bit8 :: n $> []bit8 do @dump(bin) @@ -55,7 +55,7 @@ func main() end block block - var n: bit16 :: 16#1234b16 + var n: bit16 :: 0x1234b16 var m: bit16 var bin: []bit8 :: n $> []bit8 do @dump(bin) @@ -64,7 +64,7 @@ func main() end block block - var n: bit32 :: 16#12345678b32 + var n: bit32 :: 0x12345678b32 var m: bit32 var bin: []bit8 :: n $> []bit8 do @dump(bin) @@ -73,7 +73,7 @@ func main() end block block - var n: bit64 :: 16#F012345678ABCDEFb64 + var n: bit64 :: 0xF012345678ABCDEFb64 var m: bit64 var bin: []bit8 :: n $> []bit8 do @dump(bin) diff --git a/test/kn/test0014.kn b/test/kn/test0014.kn index 7e9094fa..4f01bbd2 100644 --- a/test/kn/test0014.kn +++ b/test/kn/test0014.kn @@ -16,7 +16,7 @@ func main() block var f: file@Writer :: file@makeWriter("test_file.bin", false) - var b: []bit8 :: [16#01b8, 16#02b8, 16#03b8, 16#04b8, 16#05b8, 16#06b8, 16#07b8] + var b: []bit8 :: [0x01b8, 0x02b8, 0x03b8, 0x04b8, 0x05b8, 0x06b8, 0x07b8] do f.write(b) do f.fin() end block diff --git a/test/kn/test0015.kn b/test/kn/test0015.kn index 4b803486..0848de96 100644 --- a/test/kn/test0015.kn +++ b/test/kn/test0015.kn @@ -33,10 +33,10 @@ func main() end block block - do cui@print((16#12b8).endian().toStr()) - do cui@print((16#1234b16).endian().toStr()) - do cui@print((16#12345678b32).endian().toStr()) - do cui@print((16#12345678ABCDEF01b64).endian().toStr()) + do cui@print((0x12b8).endian().toStr()) + do cui@print((0x1234b16).endian().toStr()) + do cui@print((0x12345678b32).endian().toStr()) + do cui@print((0x12345678ABCDEF01b64).endian().toStr()) end block block @@ -59,7 +59,7 @@ func main() end for var before: []bit8 :: #[14]bit8 for i(0, 13) - do before[i] :: (i * 16#11) $ bit8 + do before[i] :: (i * 0x11) $ bit8 end for var coded: []bit8 :: lib@encrypt(before, key) do cui@print((^coded).toStr()) From 1ca7346072c43dc154dd6b12890ccd51d4093325 Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 2 Jun 2018 16:52:10 +0900 Subject: [PATCH 03/19] Modify the samples. --- package/samples/0001_kuinote/main.kn | 12 +++++------ package/samples/0002_draw_2d/main.kn | 20 +++++++++---------- package/samples/0003_draw_3d/main.kn | 2 +- package/samples/0005_input/main.kn | 6 +++--- package/samples/0009_file/main.kn | 8 ++++---- package/samples/0012_kuina_chan_model/main.kn | 4 ++-- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package/samples/0001_kuinote/main.kn b/package/samples/0001_kuinote/main.kn index 4a65852b..4b684513 100644 --- a/package/samples/0001_kuinote/main.kn +++ b/package/samples/0001_kuinote/main.kn @@ -14,12 +14,12 @@ func main() var menuMain: wnd@Menu :: wnd@makeMenu() var popupMainFile: wnd@Popup :: wnd@makePopup() do menuMain.addPopup("&File", popupMainFile) - do popupMainFile.add(16#0001, "&New") + do popupMainFile.add(0x0001, "&New") do popupMainFile.addLine() - do popupMainFile.add(16#0002, "E&xit") + do popupMainFile.add(0x0002, "E&xit") var popupMainHelp: wnd@Popup :: wnd@makePopup() do menuMain.addPopup("&Help", popupMainHelp) - do popupMainHelp.add(16#1001, "&About Kuinote...") + do popupMainHelp.add(0x1001, "&About Kuinote...") ; メニューの登録 do @wndMain.setMenu(menuMain) ; ユーザが操作を行うのを待機する @@ -40,11 +40,11 @@ end func ; メニューが選択されたときに呼ばれるイベント関数 func wndMainOnPushMenu(wnd: wnd@WndBase, id: int) switch(id) - case 16#0001 {New} + case 0x0001 {New} do @editText.setText("") {テキストを空にする} - case 16#0002 {Exit} + case 0x0002 {Exit} do @wndMain.close() {ウインドウを閉じる} - case 16#1001 {About Kuinote} + case 0x1001 {About Kuinote} do wnd@msgBox(@wndMain, "Kuinote\nVersion 1.0.0\n(C)Kuina-chan", "Kuinote", %info, %ok) end switch end func diff --git a/package/samples/0002_draw_2d/main.kn b/package/samples/0002_draw_2d/main.kn index b07198f5..cb611fff 100644 --- a/package/samples/0002_draw_2d/main.kn +++ b/package/samples/0002_draw_2d/main.kn @@ -6,23 +6,23 @@ func main() var texKuin: draw@Tex :: draw@makeTex("res/kuin.png") {画像の読み込み} var fontProportional: draw@Font :: draw@makeFont(null, 32, false, false, true, 0.0) {プロポーショナルフォントの生成} var fontMonospace: draw@Font :: draw@makeFont(null, 32, false, false, false, 40.0) {等幅フォントの生成} - do draw@clearColor(16#FF333333) {背景色の設定} + do draw@clearColor(0xFF333333) {背景色の設定} while(wnd@act()) - do draw@line(100.0, 100.0, 200.0, 200.0, 16#FFFF3333) {線分} - do draw@rectLine(300.0, 100.0, 100.0, 100.0, 16#FF33FF33) {四角形の枠線} - do draw@rect(500.0, 100.0, 100.0, 100.0, 16#FF3333FF) {四角形} - do draw@circle(750.0, 150.0, 50.0, 50.0, 16#FFFFFF33) {円} - do draw@tri(950.0, 100.0, 900.0, 200.0, 1000.0, 200.0, 16#FFFF33FF) {三角形} + do draw@line(100.0, 100.0, 200.0, 200.0, 0xFFFF3333) {線分} + do draw@rectLine(300.0, 100.0, 100.0, 100.0, 0xFF33FF33) {四角形の枠線} + do draw@rect(500.0, 100.0, 100.0, 100.0, 0xFF3333FF) {四角形} + do draw@circle(750.0, 150.0, 50.0, 50.0, 0xFFFFFF33) {円} + do draw@tri(950.0, 100.0, 900.0, 200.0, 1000.0, 200.0, 0xFFFF33FF) {三角形} for i(0, 3) do texKuin.draw(100.0 + i $ float * 200.0, 300.0, 0.0, 0.0, 150.0, 150.0, draw@white) {画像} end for - do draw@rect(175.0, 375.0, 100.0, 100.0, 16#7FFF0000) {半透明} + do draw@rect(175.0, 375.0, 100.0, 100.0, 0x7FFF0000) {半透明} do draw@blend(%add) - do draw@rect(375.0, 375.0, 100.0, 100.0, 16#FFFF0000) {加算} + do draw@rect(375.0, 375.0, 100.0, 100.0, 0xFFFF0000) {加算} do draw@blend(%sub) - do draw@rect(575.0, 375.0, 100.0, 100.0, 16#FFFF0000) {減算} + do draw@rect(575.0, 375.0, 100.0, 100.0, 0xFFFF0000) {減算} do draw@blend(%mul) - do draw@rect(775.0, 375.0, 100.0, 100.0, 16#FFFF0000) {乗算} + do draw@rect(775.0, 375.0, 100.0, 100.0, 0xFFFF0000) {乗算} do draw@blend(%alpha) do texKuin.drawScale(100.0, 500.0, 300.0, 300.0, 0.0, 0.0, 150.0, 150.0, draw@white) {拡大} do texKuin.drawRot(500.0, 575.0, 150.0, 150.0, 0.0, 0.0, 150.0, 150.0, 75.0, 75.0, -draw@cnt() $ float * lib@pi / 60.0, draw@white) {回転} diff --git a/package/samples/0003_draw_3d/main.kn b/package/samples/0003_draw_3d/main.kn index 119b932d..07c519e9 100644 --- a/package/samples/0003_draw_3d/main.kn +++ b/package/samples/0003_draw_3d/main.kn @@ -12,7 +12,7 @@ func main() var objCone: draw@Obj :: draw@makeObj("res/cone.knobj") {コーンモデルの読み込み} var texCone: draw@Tex :: draw@makeTexEvenArgb(1.0, 0.7, 0.2, 0.1) var texConeSpecular: draw@Tex :: draw@makeTexEvenArgb(2.0, 0.3, 0.3, 0.3) - do draw@clearColor(16#FF999999) {背景色の設定} + do draw@clearColor(0xFF999999) {背景色の設定} do draw@depth(true, true) {Zバッファの設定} do objBoard.pos(20.0, 20.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0, -15.0) {板モデルの位置設定} do objBox.pos(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0) {箱モデルの位置設定} diff --git a/package/samples/0005_input/main.kn b/package/samples/0005_input/main.kn index d3e947e8..d5d82942 100644 --- a/package/samples/0005_input/main.kn +++ b/package/samples/0005_input/main.kn @@ -36,7 +36,7 @@ func main() do font.draw(100.0, 700.0, "'Right' button ('Right' key): " ~ input@pad(0, %right).toStr(), draw@white) do font.draw(100.0, 750.0, "'Up' button ('Up' key): " ~ input@pad(0, %up).toStr(), draw@white) do font.draw(100.0, 800.0, "'Down' button ('Down' key): " ~ input@pad(0, %down).toStr(), draw@white) - do draw@circle(@mouseX $ float, @mouseY $ float, 20.0, 20.0, @mouseDownL ?(16#FF0000FF, 16#FFFFFF00)) + do draw@circle(@mouseX $ float, @mouseY $ float, 20.0, 20.0, @mouseDownL ?(0xFF0000FF, 0xFFFFFF00)) do font.draw(800.0, 50.0, "Key: " ~ @keyBuf, draw@white) do draw@render(60) end while @@ -67,11 +67,11 @@ end func func drawMainOnMouseEnter(wnd: wnd@Draw, x: int, y: int) do @mouseDownL :: wnd@key(%mouseL) {左ボタンを押したままウインドウ外に出て入りなおす場合の対処} - do draw@clearColor(16#FFFF9999) {ウインドウ内に入ったら背景色をピンクにする} + do draw@clearColor(0xFFFF9999) {ウインドウ内に入ったら背景色をピンクにする} end func func drawMainOnMouseLeave(wnd: wnd@Draw) - do draw@clearColor(16#FF000000) {ウインドウ外に出たら背景色を黒にする} + do draw@clearColor(0xFF000000) {ウインドウ外に出たら背景色を黒にする} end func func drawMainOnKeyChar(wnd: wnd@Draw, key: char) diff --git a/package/samples/0009_file/main.kn b/package/samples/0009_file/main.kn index 3799b912..8ebe106f 100644 --- a/package/samples/0009_file/main.kn +++ b/package/samples/0009_file/main.kn @@ -64,8 +64,8 @@ end func ; 暗号化の鍵を生成する関数 func getKey(): []bit8 ; 鍵は32byteでなければならない - ret[16#12b8, 16#34b8, 16#56b8, 16#78b8, 16#9Ab8, 16#BCb8, 16#DEb8, 16#F0b8, - |16#75b8, 16#38b8, 16#9Bb8, 16#C4b8, 16#21b8, 16#A0b8, 16#DFb8, 16#E6b8, - |16#49b8, 16#2Fb8, 16#B5b8, 16#3Db8, 16#01b8, 16#68b8, 16#7Ab8, 16#CEb8, - |16#F0b8, 16#52b8, 16#CAb8, 16#E6b8, 16#89b8, 16#D7b8, 16#4Bb8, 16#31b8] + ret[0x12b8, 0x34b8, 0x56b8, 0x78b8, 0x9Ab8, 0xBCb8, 0xDEb8, 0xF0b8, + |0x75b8, 0x38b8, 0x9Bb8, 0xC4b8, 0x21b8, 0xA0b8, 0xDFb8, 0xE6b8, + |0x49b8, 0x2Fb8, 0xB5b8, 0x3Db8, 0x01b8, 0x68b8, 0x7Ab8, 0xCEb8, + |0xF0b8, 0x52b8, 0xCAb8, 0xE6b8, 0x89b8, 0xD7b8, 0x4Bb8, 0x31b8] end func diff --git a/package/samples/0012_kuina_chan_model/main.kn b/package/samples/0012_kuina_chan_model/main.kn index 05d41150..20b437c2 100644 --- a/package/samples/0012_kuina_chan_model/main.kn +++ b/package/samples/0012_kuina_chan_model/main.kn @@ -6,7 +6,7 @@ func main() var obj: draw@Obj :: draw@makeObj("res/kuina_chan.knobj") {くいなちゃんモデルの読み込み} var texAlbedo: draw@Tex :: draw@makeTex("res/albedo.png") {くいなちゃんモデル用のアルベドテクスチャの読み込み} var texNormal: draw@Tex :: draw@makeTexArgb("res/normal.png") {くいなちゃんモデル用の法線マップテクスチャの読み込み} - do draw@clearColor(16#FFEEEEEE) {背景色の設定} + do draw@clearColor(0xFFEEEEEE) {背景色の設定} do draw@depth(true, true) {Zバッファの設定} do obj.pos(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0) {くいなちゃんモデルの位置設定} var angle: float :: 0.0 {カメラの角度} @@ -16,7 +16,7 @@ func main() do angle :+ lib@pi / 120.0 {4秒間に1周させる} do draw@camera(80.0 * lib@sin(angle), 4.0, 80.0 * lib@cos(angle), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) {カメラの設定} do obj.drawToon(0, anim, texAlbedo, null, texNormal) {くいなちゃんモデルの描画} - do obj.drawOutline(0, anim, 0.05, 16#FF664444) {輪郭線の描画} + do obj.drawOutline(0, anim, 0.05, 0xFF664444) {輪郭線の描画} do anim :: (anim + 0.5) % 60.0 {アニメーションを行う} do draw@render(60) end while From 2c7f33b89e3165bcd40e7de2c246e1016042f35e Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 2 Jun 2018 17:32:35 +0900 Subject: [PATCH 04/19] Fix the resources of the 0003 sample. --- package/samples/0003_draw_3d/res/board.knobj | Bin 404 -> 356 bytes package/samples/0003_draw_3d/res/box.knobj | Bin 2284 -> 1996 bytes package/samples/0003_draw_3d/res/cone.knobj | Bin 503084 -> 437588 bytes package/samples/0003_draw_3d/res/sphere.knobj | Bin 62932 -> 54796 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/package/samples/0003_draw_3d/res/board.knobj b/package/samples/0003_draw_3d/res/board.knobj index 58f6158aead98ce7bc7829414857855d3c73d1d8..588dc75b8dd2ef441b72e567c3fdde9eef0cb482 100644 GIT binary patch delta 40 wcmbQj{Df(O-{dq#&56w_6L%<2EMT2@TbZrFo`Ipke&R;u$;ONtlhYY>0WP5pxBvhE delta 55 zcmaFDG=+JB9~(mh14G09$p(!26U$Xt!JLVKY7-MUCmvRYN=|$b&bprg2!N_g0O#@$ A#sB~S diff --git a/package/samples/0003_draw_3d/res/box.knobj b/package/samples/0003_draw_3d/res/box.knobj index c2e93c3ce85b3b2ce17a8383c191e47c364f70f6..32b858407a7819f62f5ea7c92eed902d99d8edd2 100644 GIT binary patch delta 280 zcmaDOc!qz%@rjo`S-8qK*-b8B5}WM6C^)&BgL`ruqvYgfMo$iq#FYST`^g76l)(~w zKt%>jJ}eW8P3+-1HZv(se!%3z0TP6(PG(k|Jb~GVqw0v7{k4GAc3>lfSrjKbus{T- zg=;~~Jq#5502DlFplUxACU~2jdvYDC*yIJQ5Q!^LBPRalo~*|vIXRdO;<}Kyl@Oy> zGjdP92b5rDhx+Frhx+7Zc156bStf5`_u%LUx(=?|m;)riHaU&MjRhnDbe;Od53DSV H3=9ka&U{=b literal 2284 zcmbW3Jx&8L5QR7V6aFFm8~`YwL0anU6;dG4aRwv`BpSA)g9bPQqNAYQhK4@k5L_a> z=NYrkX7SE4(zC~F`}51l*`$+5>}%gaKc!+m4b4Ea(430-JhT8ULR}T}C1@F1fmT(_ z*PwN11KLzE--3G3HngK+z6Z*KSct#9Od zriqL5)8XJaSX*&f4!OolpT_+fxy3k_Oos1eByFDcF5j(n@LnstdhWy3Dc04^h3C7x zKuacjgx}+Pc`B{=HP(SlGnamiT>1>SbjG{-dtcoH9p|IbZT2;IMU5MSOf&c96y9qcH!n9!UFg@yCC>|~>_^Y@Dv=j=-_QNWfBB7bKTi%aBiDOX ze{nAT4(<1WY!jD$+jHw{Dn<66BT3ILUaa?5YthW*`?m#`HGrDAScl&WQz$cm=Vq?_ zUYNMxk?FYXE8)+Q`ttp2tb^xf<#!@Pk8|(wK5M}R)9yDsHImaWxn{o+*2EP5%lrU~ Cc(OkL diff --git a/package/samples/0003_draw_3d/res/cone.knobj b/package/samples/0003_draw_3d/res/cone.knobj index 7aa185ebea88cb7c57691702aec73b8be8c63b86..c65cf25530cced484affb0736a932fa8866df711 100644 GIT binary patch delta 54823 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 diff --git a/package/samples/0003_draw_3d/res/sphere.knobj b/package/samples/0003_draw_3d/res/sphere.knobj index bd20c186df62061f581db9b223968eb1077e04aa..39415c8d766d265b4c7d4e3339334935cb84a538 100644 GIT binary patch delta 4243 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 delta 15171 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 HP%-j Date: Tue, 5 Jun 2018 03:52:07 +0900 Subject: [PATCH 05/19] Add the 'list.find' and 'list.findLast' method. --- package/readme.txt | 10 ++++++++- package/sys/kuin.kn | 10 +++++++-- src/compiler/analyze.c | 12 +++++++++-- src/compiler/main.c | 2 +- src/lib_common/main.c | 46 ++++++++++++++++++++++++++++++++++++++-- src/lib_common/main.h | 6 ++++-- src/test_src/main.c | 2 +- test/correct/log0021.txt | 21 ++++++++++++++++++ test/kn/test0021.kn | 41 +++++++++++++++++++++++++++++++++++ 9 files changed, 139 insertions(+), 11 deletions(-) create mode 100644 test/correct/log0021.txt create mode 100644 test/kn/test0021.kn diff --git a/package/readme.txt b/package/readme.txt index e21b3c4e..b0bc2b2c 100644 --- a/package/readme.txt +++ b/package/readme.txt @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------- Kuin Programming Language -v.2018.5.17 +v.2018.6.17 (C) Kuina-chan ------------------------------------------------------------------------------- @@ -43,6 +43,14 @@ v.2018.5.17 4. 変更履歴 ------------------------------------------------------------------------------- +v.2018.6.17 + - 互換性が失われる変更 + - 「+**」構文の廃止と、オーバーライド元メソッドを参照する「super」構文の + 追加 + - 16進数リテラルの構文を「16#」から「0x」に変更 + - 細かな機能追加 + - list.find、list.findLastメソッドの追加 + v.2018.5.17 - 輪郭線を描画するメソッドdraw@Obj.drawOutlineの追加 - トゥーンレンダリングで描画するメソッドdraw@Obj.drawToonの追加 diff --git a/package/sys/kuin.kn b/package/sys/kuin.kn index d6152c42..c43e8920 100644 --- a/package/sys/kuin.kn +++ b/package/sys/kuin.kn @@ -125,10 +125,16 @@ end func func [d0000.knd, _any_type] _sortDescList(me_: []bit8, type: int) end func -func [d0000.knd, _any_type, _take_child] _find(me_: []bit8, type: int, item: []bit8, start: int): int +func [d0000.knd, _any_type, _take_child] _findArray(me_: []bit8, type: int, item: []bit8, start: int): int end func -func [d0000.knd, _any_type, _take_child] _findLast(me_: []bit8, type: int, item: []bit8, start: int): int +func [d0000.knd, _any_type, _take_child] _findList(me_: []bit8, type: int, item: []bit8): bool +end func + +func [d0000.knd, _any_type, _take_child] _findLastArray(me_: []bit8, type: int, item: []bit8, start: int): int +end func + +func [d0000.knd, _any_type, _take_child] _findLastList(me_: []bit8, type: int, item: []bit8): bool end func func [d0000.knd, _any_type, _take_child] _findBin(me_: []bit8, type: int, item: []bit8): int diff --git a/src/compiler/analyze.c b/src/compiler/analyze.c index a7faba19..0463b32e 100644 --- a/src/compiler/analyze.c +++ b/src/compiler/analyze.c @@ -18,9 +18,9 @@ static const Char* BuildInFuncs[] = L"endian\0 \x04", L"exist\0 \x0d", L"fill\0 \x05", - L"find\0 \x05", + L"find\0 \x0e", L"findBin\0 \x05", - L"findLast\0 \x05", + L"findLast\0 \x0e", L"findStr\0 \x06", L"findStrEx\0 \x06", L"findStrLast\0 \x06", @@ -3449,6 +3449,10 @@ static SAstExpr* RebuildExprDot(SAstExprDot* ast) member = L"sortArray"; else if (wcscmp(member, L"sortDesc") == 0) member = L"sortDescArray"; + else if (wcscmp(member, L"find") == 0) + member = L"findArray"; + else if (wcscmp(member, L"findLast") == 0) + member = L"findLastArray"; else ASSERT(False); } @@ -3459,6 +3463,10 @@ static SAstExpr* RebuildExprDot(SAstExprDot* ast) member = L"sortList"; else if (wcscmp(member, L"sortDesc") == 0) member = L"sortDescList"; + else if (wcscmp(member, L"find") == 0) + member = L"findList"; + else if (wcscmp(member, L"findLast") == 0) + member = L"findLastList"; else ASSERT(False); } diff --git a/src/compiler/main.c b/src/compiler/main.c index baf521ed..e28f5752 100644 --- a/src/compiler/main.c +++ b/src/compiler/main.c @@ -253,7 +253,7 @@ EXPORT Bool Interpret2(const U8* path, const void*(*func_get_src)(const U8*), co EXPORT void Version(S64* major, S64* minor, S64* micro) { *major = 2018; - *minor = 5; + *minor = 6; *micro = 17; } diff --git a/src/lib_common/main.c b/src/lib_common/main.c index 65020b0b..c9c4a5f2 100644 --- a/src/lib_common/main.c +++ b/src/lib_common/main.c @@ -1413,7 +1413,7 @@ EXPORT void _sortDescList(void* me_, const U8* type) MergeSortList(me_, type, False); } -EXPORT S64 _find(const void* me_, const U8* type, const void* item, S64 start) +EXPORT S64 _findArray(const void* me_, const U8* type, const void* item, S64 start) { THROWDBG(me_ == NULL, 0xc0000005); size_t size = GetSize(type[1]); @@ -1438,7 +1438,28 @@ EXPORT S64 _find(const void* me_, const U8* type, const void* item, S64 start) return -1; } -EXPORT S64 _findLast(const void* me_, const U8* type, const void* item, S64 start) +EXPORT Bool _findList(const void* me_, const U8* type, const void* item) +{ + THROWDBG(me_ == NULL, 0xc0000005); + size_t size = GetSize(type[1]); + int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1); + if (cmp == NULL) + THROW(0xe9170004); + for (; ; ) + { + void* cur = *(void**)((U8*)me_ + 0x20); + if (cur == NULL) + break; + void* value = NULL; + memcpy(&value, (U8*)cur + 0x10, size); + if (cmp(value, item) == 0) + return True; + *(void**)((U8*)me_ + 0x20) = *(void**)((U8*)cur + 0x08); + } + return False; +} + +EXPORT S64 _findLastArray(const void* me_, const U8* type, const void* item, S64 start) { THROWDBG(me_ == NULL, 0xc0000005); size_t size = GetSize(type[1]); @@ -1463,6 +1484,27 @@ EXPORT S64 _findLast(const void* me_, const U8* type, const void* item, S64 star return -1; } +EXPORT Bool _findLastList(const void* me_, const U8* type, const void* item) +{ + THROWDBG(me_ == NULL, 0xc0000005); + size_t size = GetSize(type[1]); + int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1); + if (cmp == NULL) + THROW(0xe9170004); + for (; ; ) + { + void* cur = *(void**)((U8*)me_ + 0x20); + if (cur == NULL) + break; + void* value = NULL; + memcpy(&value, (U8*)cur + 0x10, size); + if (cmp(value, item) == 0) + return True; + *(void**)((U8*)me_ + 0x20) = *(void**)cur; + } + return False; +} + EXPORT S64 _findBin(const void* me_, const U8* type, const void* item) { THROWDBG(me_ == NULL, 0xc0000005); diff --git a/src/lib_common/main.h b/src/lib_common/main.h index 746ccbe3..8512ea68 100644 --- a/src/lib_common/main.h +++ b/src/lib_common/main.h @@ -46,8 +46,10 @@ EXPORT void _sortArray(void* me_, const U8* type); EXPORT void _sortDescArray(void* me_, const U8* type); EXPORT void _sortList(void* me_, const U8* type); EXPORT void _sortDescList(void* me_, const U8* type); -EXPORT S64 _find(const void* me_, const U8* type, const void* item, S64 start); -EXPORT S64 _findLast(const void* me_, const U8* type, const void* item, S64 start); +EXPORT S64 _findArray(const void* me_, const U8* type, const void* item, S64 start); +EXPORT Bool _findList(const void* me_, const U8* type, const void* item); +EXPORT S64 _findLastArray(const void* me_, const U8* type, const void* item, S64 start); +EXPORT Bool _findLastList(const void* me_, const U8* type, const void* item); EXPORT S64 _findBin(const void* me_, const U8* type, const void* item); EXPORT void _fill(void* me_, const U8* type, const void* value); EXPORT void* _min(const void* me_, const U8* type); diff --git a/src/test_src/main.c b/src/test_src/main.c index 6f123b6d..1a4df90a 100644 --- a/src/test_src/main.c +++ b/src/test_src/main.c @@ -10,7 +10,7 @@ #include #define LANG (0) -#define TEST_NUM (21) +#define TEST_NUM (22) #pragma comment(lib, "compiler.lib") diff --git a/test/correct/log0021.txt b/test/correct/log0021.txt new file mode 100644 index 00000000..f583cb61 --- /dev/null +++ b/test/correct/log0021.txt @@ -0,0 +1,21 @@ +Begin: ../../test/output/output0021.exe +Excpt: 80000003 +> 3 +> 5 +> Not found. +> 3 +> Not found. +> Not found. +> 3 +> 5 +> Not found. +> 3 +> Not found. +> Not found. +> 3 +> 5 +> Not found. +> 3 +> Not found. +> Not found. +end: ../../test/output/output0021.exe diff --git a/test/kn/test0021.kn b/test/kn/test0021.kn new file mode 100644 index 00000000..e3d093cc --- /dev/null +++ b/test/kn/test0021.kn @@ -0,0 +1,41 @@ +func main() + for(1, 3) + block + var a: list :: #list + do a.add(3) + do a.add(5) + do a.head() + if(a.find(3)) + do cui@print(a.get().toStr()) + else + do cui@print("Not found.") + end if + if(a.find(5)) + do cui@print(a.get().toStr()) + else + do cui@print("Not found.") + end if + if(a.find(7)) + do cui@print(a.get().toStr()) + else + do cui@print("Not found.") + end if + do a.tail() + if(a.findLast(3)) + do cui@print(a.get().toStr()) + else + do cui@print("Not found.") + end if + if(a.findLast(5)) + do cui@print(a.get().toStr()) + else + do cui@print("Not found.") + end if + if(a.findLast(7)) + do cui@print(a.get().toStr()) + else + do cui@print("Not found.") + end if + end block + end for +end func From 4e8540619f7e84e6c03c37bf9256d4d7db152dc6 Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 9 Jun 2018 05:51:01 +0900 Subject: [PATCH 06/19] Add the 'TreeMulti' class. --- package/sys/wnd.kn | 42 +++++++- src/compiler/analyze.c | 4 +- src/compiler/assemble.c | 2 + src/kuin_editor/doc.kn | 2 +- src/kuin_editor/doc_ar.kn | 204 ++++++++++++++++++++++--------------- src/kuin_editor/doc_src.kn | 2 +- src/kuin_editor/form.kn | 4 +- src/lib_wnd/main.cpp | 116 ++++++++++++++++----- src/lib_wnd/main.h | 3 + 9 files changed, 261 insertions(+), 118 deletions(-) diff --git a/package/sys/wnd.kn b/package/sys/wnd.kn index 73022178..c6c3373c 100644 --- a/package/sys/wnd.kn +++ b/package/sys/wnd.kn @@ -474,7 +474,7 @@ end class +var onSel: func<(@WndBase)> end class -+class Tree(@WndBase) ++class TreeBase(@WndBase) *func [d0001.knd, _wndBaseDtor, _force] _dtor() end func @@ -493,16 +493,42 @@ end class +func [d0001.knd, _treeAllowDraggingToRoot] allowDraggingToRoot(enabled: bool) end func + var draggable_: int + var draggingItem: int + +var onSel: func<(@WndBase)> + +var onMoveNode: func<(@WndBase)> +end class + ++class Tree(@TreeBase) + *func [d0001.knd, _wndBaseDtor, _force] _dtor() + end func + +func [d0001.knd, _treeSetSel] setSel(node: @TreeNode) end func +func [d0001.knd, _treeGetSel, _make_instance] getSel(me2: @TreeNode): @TreeNode end func +end class - var draggable_: int - var draggingItem: int - +var onSel: func<(@WndBase)> - +var onMoveNode: func<(@WndBase)> ++class TreeMulti(@TreeBase) + *func [d0001.knd, _wndBaseDtor, _force] _dtor() + end func + + +func [d0001.knd, _treeMultiSetSel] setSel(nodes: []@TreeNode) + end func + + +func getSel(): []@TreeNode + var result: list<@TreeNode> :: #list<@TreeNode> + var node: @TreeNode :: me.getSelImpl(null) + while(node <>& null) + do result.add(node) + do node :: me.getSelImpl(node) + end while + ret result.toArray() + end func + + func [d0001.knd, _treeMultiGetSel, _make_instance] getSelImpl(me2: @TreeNode, node: @TreeNode): @TreeNode + end func end class +class TreeNode() @@ -778,6 +804,12 @@ end func end if end func ++func [d0001.knd, _makeTreeMulti, _make_instance] makeTreeMulti(me2: @TreeMulti, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor): @TreeMulti + if(parent <>& null) + do parent.addChild(me2) + end if +end func + +func [d0001.knd, _makeSplitX, _make_instance] makeSplitX(me2: @SplitX, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor): @SplitX if(parent <>& null) do parent.addChild(me2) diff --git a/src/compiler/analyze.c b/src/compiler/analyze.c index 0463b32e..ed5c7ff7 100644 --- a/src/compiler/analyze.c +++ b/src/compiler/analyze.c @@ -1170,7 +1170,9 @@ static void RebuildClass(SAstClass* ast) { SAstArg* arg1 = (SAstArg*)node1->Data; SAstArg* arg2 = (SAstArg*)node2->Data; - if (!CmpType(arg1->Type, arg2->Type) || ((SAst*)arg1)->Name != NULL && ((SAst*)arg2)->Name != NULL && wcscmp(((SAst*)arg1)->Name, ((SAst*)arg2)->Name) != 0 || arg1->RefVar != arg2->RefVar) + if (((SAst*)arg1->Type)->TypeId == AstTypeId_TypeUser && ((SAst*)arg1->Type)->RefItem == NULL || + ((SAst*)arg2->Type)->TypeId == AstTypeId_TypeUser && ((SAst*)arg2->Type)->RefItem == NULL || + !CmpType(arg1->Type, arg2->Type) || ((SAst*)arg1)->Name != NULL && ((SAst*)arg2)->Name != NULL && wcscmp(((SAst*)arg1)->Name, ((SAst*)arg2)->Name) != 0 || arg1->RefVar != arg2->RefVar) { Err(L"EA0009", item->Def->Pos, member_name); return; diff --git a/src/compiler/assemble.c b/src/compiler/assemble.c index 05ce411b..7ab69c58 100644 --- a/src/compiler/assemble.c +++ b/src/compiler/assemble.c @@ -933,6 +933,7 @@ static void GcDec(int reg_i, int reg_f, const SAstType* type) ListAdd(PackAsm->Asms, AsmJE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True)))); ListAdd(PackAsm->Asms, AsmDEC(ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00))); #if defined(_DEBUG) + /* { // Since reference counters rarely exceeds 0x10, it is regarded as memory corruption. SAsmLabel* lbl2 = AsmLabel(); @@ -941,6 +942,7 @@ static void GcDec(int reg_i, int reg_f, const SAstType* type) ListAdd(PackAsm->Asms, AsmINT(ValImmU(8, 0x03))); ListAdd(PackAsm->Asms, lbl2); } + */ #endif ListAdd(PackAsm->Asms, AsmCMP(ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00), ValImmU(8, 0x00))); ListAdd(PackAsm->Asms, AsmJNE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True)))); diff --git a/src/kuin_editor/doc.kn b/src/kuin_editor/doc.kn index 36561e0b..99c6e8c2 100644 --- a/src/kuin_editor/doc.kn +++ b/src/kuin_editor/doc.kn @@ -24,7 +24,7 @@ +func updateProp(listView: wnd@ListView) end func - +func updateTree(tree: wnd@Tree) + +func updateTree(tree: wnd@TreeMulti) end func +func updateList(list_: wnd@List) diff --git a/src/kuin_editor/doc_ar.kn b/src/kuin_editor/doc_ar.kn index fc96f69e..18ccd0af 100644 --- a/src/kuin_editor/doc_ar.kn +++ b/src/kuin_editor/doc_ar.kn @@ -6,7 +6,7 @@ do me.pageX :: -me.scrollOffsetX do me.pageY :: -me.scrollOffsetY do me.mode :: %none - do me.hold :: null + do me.holds :: #list<@Obj2d> do me.ctrl :: 0 end func @@ -60,46 +60,51 @@ +*func draw(width: int, height: int) do draw@rect(0.0, 0.0, width $ float, height $ float, \common@colorBack) - do drawRecursion(me.obj2dRoot, me.pageX, me.pageY, me.hold) + do drawRecursion(me.obj2dRoot, me.pageX, me.pageY, me.holds) - func drawRecursion(obj: @Obj2d, pageX: int, pageY: int, hold: @Obj2d) - if(hold =& obj) + func drawRecursion(obj: @Obj2d, pageX: int, pageY: int, holds: list<@Obj2d>) + do holds.head() + if(holds.find(obj)) do draw@rectLine((obj.absX - 3 - pageX) $ float, (obj.absY - 3 - pageY) $ float, (obj.width + 6) $ float, (obj.height + 6) $ float, 0xFF6666FF) do draw@rectLine((obj.absX - 4 - pageX) $ float, (obj.absY - 4 - pageY) $ float, (obj.width + 8) $ float, (obj.height + 8) $ float, 0xFF6666FF) end if do obj.draw(pageX, pageY) do obj.children.head() while(!obj.children.term()) - do drawRecursion(obj.children.get(), pageX, pageY, hold) + do drawRecursion(obj.children.get(), pageX, pageY, holds) do obj.children.next() end while end func end func +*func updateProp(listView: wnd@ListView) - if(me.hold <>& null) - var parent: @Obj2d :: me.hold.parent + do me.holds.head() + while(!me.holds.term()) + var obj: @Obj2d :: me.holds.get() + var parent: @Obj2d :: obj.parent var x: int :: 0 var y: int :: 0 if(parent <>& null) do x :: parent.absX do y :: parent.absY end if - do me.hold.updateProp(listView, x, y) - end if + do obj.updateProp(listView, x, y) + do me.holds.next() + end while end func - +*func updateTree(tree: wnd@Tree) - do updateTreeRecursion(me.hold, tree, tree.root(), me.obj2dRoot) + +*func updateTree(tree: wnd@TreeMulti) + do updateTreeRecursion(me.holds, tree, tree.root(), me.obj2dRoot) - func updateTreeRecursion(hold: @Obj2d, tree: wnd@Tree, node: wnd@TreeNode, obj: @Obj2d) + func updateTreeRecursion(holds: list<@Obj2d>, tree: wnd@TreeMulti, node: wnd@TreeNode, obj: @Obj2d) var node2: wnd@TreeNode :: node.addChild(obj.objName) - if(hold =& obj) - do tree.setSel(node2) + do holds.head() + if(holds.find(obj)) + do tree.setSel([node2]) end if do obj.children.head() while(!obj.children.term()) - do updateTreeRecursion(hold, tree, node2, obj.children.get()) + do updateTreeRecursion(holds, tree, node2, obj.children.get()) do obj.children.next() end while end func @@ -111,25 +116,22 @@ end func +*func treeItemOnSel() - var sel: wnd@TreeNode :: \form@treeItem.getSel() - do me.hold :: selRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot, sel) + var sels: []wnd@TreeNode :: \form@treeItem.getSel() + do me.holds :: #list<@Obj2d> + do selRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot, sels, me.holds) do \form@paintDrawEditor() - func selRecursion(node: wnd@TreeNode, obj: @Obj2d, sel: wnd@TreeNode): @Obj2d - if(node = sel) - ret obj + func selRecursion(node: wnd@TreeNode, obj: @Obj2d, sels: []wnd@TreeNode, holds: list<@Obj2d>) + if(sels.find(node, 0) <> -1) + do holds.add(obj) end if do obj.children.head() var node2: wnd@TreeNode :: node.firstChild() while(!obj.children.term() & node2 <>& null) - var result: @Obj2d :: selRecursion(node2, obj.children.get(), sel) - if(result <>& null) - ret result - end if + do selRecursion(node2, obj.children.get(), sels, holds) do node2 :: node2.next() do obj.children.next() end while - ret null end func end func @@ -186,7 +188,7 @@ end func +*func listPropOnMouseDoubleClick(listView: wnd@ListView) - if(me.hold =& null) + if(^me.holds = 0) ret end if var sel: int :: listView.getSel() @@ -195,20 +197,23 @@ end if var prop: []char :: listView.getText(sel, 0) var value: []char :: listView.getText(sel, 1) - do value :: wndex@inputBox(\form@wndMain, me.hold.objName ~ "." ~ prop, \common@title, value, null) + do me.holds.head() + do value :: wndex@inputBox(\form@wndMain, me.holds.get().objName ~ "." ~ prop, \common@title, value, null) if(value =& null) ret end if + do me.holds.head() + var value2: int switch(prop) case "x" if(value.toInt(&value2)) var parentValue: int - if(me.hold.parent =& null) + if(me.holds.get().parent =& null) do parentValue :: 0 else - do parentValue :: me.hold.parent.absX + do parentValue :: me.holds.get().parent.absX end if do value :: (value2 + parentValue).toStr() else @@ -217,10 +222,10 @@ case "y" if(value.toInt(&value2)) var parentValue: int - if(me.hold.parent =& null) + if(me.holds.get().parent =& null) do parentValue :: 0 else - do parentValue :: me.hold.parent.absY + do parentValue :: me.holds.get().parent.absY end if do value :: (value2 + parentValue).toStr() else @@ -232,7 +237,10 @@ do prop :: "y" end switch - do me.hold.setProp(prop, value) + while(!me.holds.term()) + do me.holds.get().setProp(prop, value) + do me.holds.next() + end while do me.changed :: true do \form@updateProp() do \form@paintDrawEditor() @@ -242,22 +250,25 @@ var x2: int :: x + me.pageX var y2: int :: y + me.pageY if(me.ctrl <= 0) - do me.hold :: selRecursion(me.obj2dRoot, x2, y2) - if(me.hold =& null) - do me.hold :: me.obj2dRoot + var obj: @Obj2d :: selRecursion(me.obj2dRoot, x2, y2) + if(obj =& null) + do obj :: me.obj2dRoot end if - if(me.hold.absX + me.hold.width - resizeArea <= x2 & me.hold.absY + me.hold.height - resizeArea <= y2) + if(obj.absX + obj.width - resizeArea <= x2 & obj.absY + obj.height - resizeArea <= y2) do me.mode :: %resize - do me.holdOffsetX :: me.hold.absX + me.hold.width - x2 - do me.holdOffsetY :: me.hold.absY + me.hold.height - y2 - elif(me.hold =& me.obj2dRoot) + do me.holdOffsetX :: obj.absX + obj.width - x2 + do me.holdOffsetY :: obj.absY + obj.height - y2 + elif(obj =& me.obj2dRoot) do me.mode :: %none else do me.mode :: %move - do me.holdOffsetX :: me.hold.absX - x2 - do me.holdOffsetY :: me.hold.absY - y2 + do me.holdOffsetX :: obj.absX - x2 + do me.holdOffsetY :: obj.absY - y2 end if + + do me.holds :: #list<@Obj2d> + do me.holds.add(obj) else if (\form@getLockingEditor()) do \form@showMsgRunning() @@ -272,14 +283,16 @@ var minHeight: int do obj.getMinMaxSize(&minWidth, &minHeight, &, &) do obj.init(me.getDefaultName(name), x2, y2, minWidth, minHeight) - if(me.hold =& null) + if(^me.holds = 0) do obj.parent :: me.obj2dRoot do me.obj2dRoot.children.add(obj) else - do obj.parent :: me.hold - do me.hold.children.add(obj) + do me.holds.head() + do obj.parent :: me.holds.get() + do me.holds.get().children.add(obj) end if - do me.hold :: obj + do me.holds :: #list<@Obj2d> + do me.holds.add(obj) end if do me.changed :: true do \form@paintDrawEditor() @@ -311,7 +324,7 @@ do me.resizeObj2d(x + me.pageX, y + me.pageY) do me.mode :: %none do me.ctrl :: 0 - do me.hold :: null + do me.holds :: #list<@Obj2d> do \form@updateTree() do \form@updateProp() do \form@paintDrawEditor() @@ -407,19 +420,24 @@ +*func setMouseImg(): wnd@MouseImg switch(me.mode) case %none - if(me.hold <>& null) + if(^me.holds <> 0) var x: int var y: int do input@mousePos(&x, &y) do \form@drawEditor.screenToClient(&x, &y, x, y) do x :+ me.pageX do y :+ me.pageY - if(me.hold.absX <= x & me.hold.absY <= y & x <= me.hold.absX + me.hold.width & y <= me.hold.absY + me.hold.height) - if(me.hold.absX + me.hold.width - resizeArea <= x & me.hold.absY + me.hold.height - resizeArea <= y) - ret %resizeLTRD + do me.holds.head() + while(!me.holds.term()) + var obj: @Obj2d :: me.holds.get() + if(obj.absX <= x & obj.absY <= y & x <= obj.absX + obj.width & y <= obj.absY + obj.height) + if(obj.absX + obj.width - resizeArea <= x & obj.absY + obj.height - resizeArea <= y) + ret %resizeLTRD + end if + ret %move end if - ret %move - end if + do me.holds.next() + end while end if ret %arrow case %put @@ -454,26 +472,27 @@ end func +*func cmdDel() - if(me.hold =& null | me.hold =& me.obj2dRoot) + if(^me.holds = 0) ret end if - do delRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot, me.hold) + do delRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot, me.holds) do me.changed :: true do \form@updateTree() do \form@updateProp() do \form@paintDrawEditor() - func delRecursion(node: wnd@TreeNode, obj: @Obj2d, hold: @Obj2d): bool + func delRecursion(node: wnd@TreeNode, obj: @Obj2d, holds: list<@Obj2d>): bool var node2: wnd@TreeNode :: node.firstChild() do obj.children.head() while(!obj.children.term() & node2 <>& null) var childObj: @Obj2d :: obj.children.get() - if(hold =& childObj) + do holds.head() + if(holds.find(childObj)) do node.delChild(node2) do obj.children.del() ret true end if - if(delRecursion(node2, childObj, hold)) + if(delRecursion(node2, childObj, holds)) ret true end if do node2 :: node2.next() @@ -507,7 +526,7 @@ var pageX: int var pageY: int var mode: Mode - var hold: @Obj2d + var holds: list<@Obj2d> var ctrl: int var holdOffsetX: int var holdOffsetY: int @@ -558,37 +577,48 @@ func resizeObj2d(x: int, y: int) do me.stick(&x, &y) - var width: int :: x - me.hold.absX + me.holdOffsetX - var height: int :: y - me.hold.absY + me.holdOffsetY - var minWidth: int - var minHeight: int - var maxWidth: int - var maxHeight: int - do me.hold.getMinMaxSize(&minWidth, &minHeight, &maxWidth, &maxHeight) - if(width < minWidth) - do width :: minWidth - end if - if(width > maxWidth) - do width :: maxWidth - end if - if(height < minHeight) - do height :: minHeight - end if - if(height > maxHeight) - do height :: maxHeight - end if - do me.hold.width :: width - do me.hold.height :: height + do me.holds.head() + while(!me.holds.term()) + var obj: @Obj2d :: me.holds.get() + var width: int :: x - obj.absX + me.holdOffsetX + var height: int :: y - obj.absY + me.holdOffsetY + var minWidth: int + var minHeight: int + var maxWidth: int + var maxHeight: int + do obj.getMinMaxSize(&minWidth, &minHeight, &maxWidth, &maxHeight) + if(width < minWidth) + do width :: minWidth + end if + if(width > maxWidth) + do width :: maxWidth + end if + if(height < minHeight) + do height :: minHeight + end if + if(height > maxHeight) + do height :: maxHeight + end if + do obj.width :: width + do obj.height :: height + do me.holds.next() + end while end func func moveObj2d(x: int, y: int) - do me.hold.absX :: x + me.holdOffsetX - do me.hold.absY :: y + me.holdOffsetY - do me.stick(&me.hold.absX, &me.hold.absY) + do me.holds.head() + while(!me.holds.term()) + var obj: @Obj2d :: me.holds.get() + do obj.absX :: x + me.holdOffsetX + do obj.absY :: y + me.holdOffsetY + do me.stick(&obj.absX, &obj.absY) + do me.holds.next() + end while end func func stick(x: &int, y: &int) - var parent: @Obj2d :: me.hold.parent + { + var parent: @Obj2d :: me.holds.parent if(parent =& null) ret end if @@ -607,7 +637,7 @@ do parent.children.head() while(!parent.children.term()) var child: @Obj2d :: parent.children.get() - if(child <>& me.hold) + if(child <>& me.holds) if((x - child.absX).abs() <= stickingArea) do x :: child.absX end if @@ -623,6 +653,8 @@ end if do parent.children.next() end while + } + end func end class @@ -632,6 +664,10 @@ end class do me.init("root", 0, 0, 800, 450) end func + +*func cmp(t: kuin@Class): int + ret t =& me ?(0, 1) + end func + +func init(objName: []char, x: int, y: int, width: int, height: int) do me.parent :: null do me.children :: #list diff --git a/src/kuin_editor/doc_src.kn b/src/kuin_editor/doc_src.kn index 5ae78eee..6272d4ae 100644 --- a/src/kuin_editor/doc_src.kn +++ b/src/kuin_editor/doc_src.kn @@ -192,7 +192,7 @@ end func end while end func - +*func updateTree(tree: wnd@Tree) + +*func updateTree(tree: wnd@TreeMulti) ; TODO: end func diff --git a/src/kuin_editor/form.kn b/src/kuin_editor/form.kn index 1deeb0e0..bc5f0b21 100644 --- a/src/kuin_editor/form.kn +++ b/src/kuin_editor/form.kn @@ -1,5 +1,5 @@ +var wndMain: wnd@Wnd -+var treeItem: wnd@Tree ++var treeItem: wnd@TreeMulti +var listInfo: wnd@List var editFile: wnd@Edit +var drawEditor: wnd@Draw @@ -34,7 +34,7 @@ var drag: bool do @wndMain.onClose :: @wndMainOnClose do @wndMain.onActivate :: @wndMainOnActivate do @wndMain.onPushMenu :: @wndMainOnPushMenu - do @treeItem :: wnd@makeTree(@wndMain, 12, 12, 244, 466, %fix, %fix) + do @treeItem :: wnd@makeTreeMulti(@wndMain, 12, 12, 244, 466, %fix, %fix) do @treeItem.draggable(true) do @treeItem.allowDraggingToRoot(false) do @treeItem.onSel :: @treeItemOnSel diff --git a/src/lib_wnd/main.cpp b/src/lib_wnd/main.cpp index b4f83be7..c2752025 100644 --- a/src/lib_wnd/main.cpp +++ b/src/lib_wnd/main.cpp @@ -45,6 +45,7 @@ enum EWndKind WndKind_Pager, WndKind_Tab, WndKind_Tree, + WndKind_TreeMulti, WndKind_SplitX, WndKind_SplitY, WndKind_ScrollX, @@ -138,15 +139,20 @@ struct SRadio void* OnPush; }; -struct SEdit +struct SEditBase { SWndBase WndBase; void* OnChange; }; +struct SEdit +{ + SEditBase EditBase; +}; + struct SEditMulti { - SWndBase WndBase; + SEditBase EditBase; }; struct SList @@ -228,7 +234,7 @@ struct STab void* OnSel; }; -struct STree +struct STreeBase { SWndBase WndBase; Bool Draggable; @@ -238,6 +244,16 @@ struct STree void* OnMoveNode; }; +struct STree +{ + STreeBase TreeBase; +}; + +struct STreeMulti +{ + STreeBase TreeBase; +}; + struct STreeNode { SClass Class; @@ -1074,7 +1090,7 @@ EXPORT_CPP SClass* _makeEdit(SClass* me_, SClass* parent, S64 x, S64 y, S64 widt { SEdit* me2 = reinterpret_cast(me_); SetCtrlParam(reinterpret_cast(me_), reinterpret_cast(parent), WndKind_Edit, WC_EDIT, WS_EX_CLIENTEDGE, WS_VISIBLE | WS_CHILD | WS_TABSTOP | ES_AUTOHSCROLL, x, y, width, height, L"", WndProcEdit, anchorX, anchorY); - me2->OnChange = NULL; + reinterpret_cast(me2)->OnChange = NULL; return me_; } @@ -1484,11 +1500,24 @@ EXPORT_CPP SClass* _makeTree(SClass* me_, SClass* parent, S64 x, S64 y, S64 widt { STree* me2 = reinterpret_cast(me_); SetCtrlParam(reinterpret_cast(me_), reinterpret_cast(parent), WndKind_Tree, WC_TREEVIEW, WS_EX_CLIENTEDGE, WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_LINESATROOT, x, y, width, height, L"", WndProcTree, anchorX, anchorY); - me2->Draggable = False; - me2->AllowDraggingToRoot = False; - me2->DraggingItem = NULL; - me2->OnSel = NULL; - me2->OnMoveNode = NULL; + reinterpret_cast(me2)->Draggable = False; + reinterpret_cast(me2)->AllowDraggingToRoot = False; + reinterpret_cast(me2)->DraggingItem = NULL; + reinterpret_cast(me2)->OnSel = NULL; + reinterpret_cast(me2)->OnMoveNode = NULL; + return me_; +} + +EXPORT_CPP SClass* _makeTreeMulti(SClass* me_, SClass* parent, S64 x, S64 y, S64 width, S64 height, S64 anchorX, S64 anchorY) +{ + STree* me2 = reinterpret_cast(me_); + SetCtrlParam(reinterpret_cast(me_), reinterpret_cast(parent), WndKind_TreeMulti, WC_TREEVIEW, WS_EX_CLIENTEDGE, WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_LINESATROOT, x, y, width, height, L"", WndProcTree, anchorX, anchorY); + TreeView_SetExtendedStyle(reinterpret_cast(me2)->WndHandle, TVS_EX_MULTISELECT, TVS_EX_MULTISELECT); + reinterpret_cast(me2)->Draggable = False; + reinterpret_cast(me2)->AllowDraggingToRoot = False; + reinterpret_cast(me2)->DraggingItem = NULL; + reinterpret_cast(me2)->OnSel = NULL; + reinterpret_cast(me2)->OnMoveNode = NULL; return me_; } @@ -1517,12 +1546,12 @@ EXPORT_CPP SClass* _treeRoot(SClass* me_, SClass* me2) EXPORT_CPP void _treeDraggable(SClass* me_, Bool enabled) { - reinterpret_cast(me_)->Draggable = enabled; + reinterpret_cast(me_)->Draggable = enabled; } EXPORT_CPP void _treeAllowDraggingToRoot(SClass* me_, Bool enabled) { - reinterpret_cast(me_)->AllowDraggingToRoot = enabled; + reinterpret_cast(me_)->AllowDraggingToRoot = enabled; } EXPORT_CPP void _treeSetSel(SClass* me_, SClass* node) @@ -1539,6 +1568,44 @@ EXPORT_CPP SClass* _treeGetSel(SClass* me_, SClass* me2) STreeNode* me4 = reinterpret_cast(me2); me4->WndHandle = me3->WndHandle; me4->Item = TreeView_GetSelection(me3->WndHandle); + if (me4->Item == NULL) + return NULL; + return me2; +} + +EXPORT_CPP void _treeMultiSetSel(SClass* me_, void* nodes) +{ + SWndBase* me2 = reinterpret_cast(me_); + S64 len = *(S64*)((U8*)nodes + 0x08); + void** ptr = (void**)((U8*)nodes + 0x10); + S64 i; + for (i = 0; i < len; i++) + { + STreeNode* node2 = reinterpret_cast(ptr[i]); + THROWDBG(me2->WndHandle != node2->WndHandle, 0xe9170006); + if (i == 0) + TreeView_Select(me2->WndHandle, node2->Item, TVGN_CARET); + else + { + TVITEM ti; + ti.mask = TVIF_STATE; + ti.hItem = node2->Item; + ti.state = LVIS_SELECTED; + ti.stateMask = LVIS_SELECTED; + TreeView_SetItem(me2->WndHandle, &ti); + } + } +} + +EXPORT_CPP SClass* _treeMultiGetSel(SClass* me_, SClass* me2, SClass* node) +{ + SWndBase* me3 = reinterpret_cast(me_); + STreeNode* me4 = reinterpret_cast(me2); + STreeNode* node2 = reinterpret_cast(node); + me4->WndHandle = me3->WndHandle; + me4->Item = TreeView_GetNextItem(me3->WndHandle, node2 == NULL ? NULL : node2->Item, node2 == NULL ? TVGN_CARET : TVGN_NEXTSELECTED); + if (me4->Item == NULL) + return NULL; return me2; } @@ -2106,8 +2173,8 @@ static void CommandAndNotify(HWND wnd, UINT msg, WPARAM w_param, LPARAM l_param) switch (HIWORD(w_param)) { case EN_CHANGE: - if (edit->OnChange != NULL) - Call1Asm(IncWndRef(reinterpret_cast(wnd_ctrl2)), edit->OnChange); + if (reinterpret_cast(edit)->OnChange != NULL) + Call1Asm(IncWndRef(reinterpret_cast(wnd_ctrl2)), reinterpret_cast(edit)->OnChange); // TODO: break; case EN_HSCROLL: @@ -2194,8 +2261,9 @@ static void CommandAndNotify(HWND wnd, UINT msg, WPARAM w_param, LPARAM l_param) } break; case WndKind_Tree: + case WndKind_TreeMulti: { - STree* tree = reinterpret_cast(wnd_ctrl2); + STreeBase* tree = reinterpret_cast(wnd_ctrl2); switch (reinterpret_cast(l_param)->code) { case TVN_BEGINDRAG: @@ -2972,11 +3040,11 @@ static LRESULT CALLBACK WndProcTree(HWND wnd, UINT msg, WPARAM w_param, LPARAM l { SWndBase* wnd2 = ToWnd(wnd); STree* wnd3 = reinterpret_cast(wnd2); - ASSERT(wnd2->Kind == WndKind_Tree); + ASSERT(wnd2->Kind == WndKind_Tree || wnd2->Kind == WndKind_TreeMulti); switch (msg) { case WM_MOUSEMOVE: - if (wnd3->DraggingItem != NULL) + if (reinterpret_cast(wnd3)->DraggingItem != NULL) { POINT point; TVHITTESTINFO hit_test = { 0 }; @@ -2998,7 +3066,7 @@ static LRESULT CALLBACK WndProcTree(HWND wnd, UINT msg, WPARAM w_param, LPARAM l } return 0; case WM_LBUTTONUP: - if (wnd3->DraggingItem != NULL) + if (reinterpret_cast(wnd3)->DraggingItem != NULL) { POINT point; TVHITTESTINFO hit_test = { 0 }; @@ -3009,7 +3077,7 @@ static LRESULT CALLBACK WndProcTree(HWND wnd, UINT msg, WPARAM w_param, LPARAM l hit_test.pt.y = point.y; ScreenToClient(wnd, &hit_test.pt); HTREEITEM item = reinterpret_cast(SendMessage(wnd, TVM_HITTEST, 0, reinterpret_cast(&hit_test))); - if (wnd3->DraggingItem != item && (wnd3->AllowDraggingToRoot || item != NULL)) + if (reinterpret_cast(wnd3)->DraggingItem != item && (reinterpret_cast(wnd3)->AllowDraggingToRoot || item != NULL)) { Bool success = True; { @@ -3017,7 +3085,7 @@ static LRESULT CALLBACK WndProcTree(HWND wnd, UINT msg, WPARAM w_param, LPARAM l HTREEITEM item2 = item; while (item2 != NULL) { - if (item2 == wnd3->DraggingItem) + if (item2 == reinterpret_cast(wnd3)->DraggingItem) { success = False; break; @@ -3028,16 +3096,16 @@ static LRESULT CALLBACK WndProcTree(HWND wnd, UINT msg, WPARAM w_param, LPARAM l if (success) { Char buf[1025]; - CopyTreeNodeRecursion(wnd, item, wnd3->DraggingItem, buf); - TreeView_DeleteItem(wnd, wnd3->DraggingItem); - if (wnd3->OnMoveNode) - Call1Asm(IncWndRef(reinterpret_cast(wnd3)), wnd3->OnMoveNode); + CopyTreeNodeRecursion(wnd, item, reinterpret_cast(wnd3)->DraggingItem, buf); + TreeView_DeleteItem(wnd, reinterpret_cast(wnd3)->DraggingItem); + if (reinterpret_cast(wnd3)->OnMoveNode) + Call1Asm(IncWndRef(reinterpret_cast(wnd3)), reinterpret_cast(wnd3)->OnMoveNode); } } ImageList_DragShowNolock(TRUE); ImageList_DragLeave(NULL); ImageList_EndDrag(); - wnd3->DraggingItem = NULL; + reinterpret_cast(wnd3)->DraggingItem = NULL; } return 0; } diff --git a/src/lib_wnd/main.h b/src/lib_wnd/main.h index 3651e7dd..e2202c77 100644 --- a/src/lib_wnd/main.h +++ b/src/lib_wnd/main.h @@ -99,6 +99,7 @@ EXPORT_CPP void _tabSetSel(SClass* me_, S64 idx); EXPORT_CPP S64 _tabGetSel(SClass* me_); EXPORT_CPP void _tabGetPosInner(SClass* me_, S64* x, S64* y, S64* width, S64* height); EXPORT_CPP SClass* _makeTree(SClass* me_, SClass* parent, S64 x, S64 y, S64 width, S64 height, S64 anchorX, S64 anchorY); +EXPORT_CPP SClass* _makeTreeMulti(SClass* me_, SClass* parent, S64 x, S64 y, S64 width, S64 height, S64 anchorX, S64 anchorY); EXPORT_CPP void _treeClear(SClass* me_); EXPORT_CPP void _treeExpand(SClass* me_, Bool expand); EXPORT_CPP SClass* _treeRoot(SClass* me_, SClass* me2); @@ -106,6 +107,8 @@ EXPORT_CPP void _treeDraggable(SClass* me_, Bool enabled); EXPORT_CPP void _treeAllowDraggingToRoot(SClass* me_, Bool enabled); EXPORT_CPP void _treeSetSel(SClass* me_, SClass* node); EXPORT_CPP SClass* _treeGetSel(SClass* me_, SClass* me2); +EXPORT_CPP void _treeMultiSetSel(SClass* me_, void* nodes); +EXPORT_CPP SClass* _treeMultiGetSel(SClass* me_, SClass* me2, SClass* node); EXPORT_CPP SClass* _treeNodeAddChild(SClass* me_, SClass* me2, const U8* name); EXPORT_CPP SClass* _treeNodeInsChild(SClass* me_, SClass* me2, SClass* node, const U8* name); EXPORT_CPP void _treeNodeDelChild(SClass* me_, SClass* node); From 6828ee99bae6ab29311f68dbc6abd9af1e27903b Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 9 Jun 2018 06:10:53 +0900 Subject: [PATCH 07/19] A trivial change. --- src/compiler/assemble.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/assemble.c b/src/compiler/assemble.c index 7ab69c58..05ce411b 100644 --- a/src/compiler/assemble.c +++ b/src/compiler/assemble.c @@ -933,7 +933,6 @@ static void GcDec(int reg_i, int reg_f, const SAstType* type) ListAdd(PackAsm->Asms, AsmJE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True)))); ListAdd(PackAsm->Asms, AsmDEC(ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00))); #if defined(_DEBUG) - /* { // Since reference counters rarely exceeds 0x10, it is regarded as memory corruption. SAsmLabel* lbl2 = AsmLabel(); @@ -942,7 +941,6 @@ static void GcDec(int reg_i, int reg_f, const SAstType* type) ListAdd(PackAsm->Asms, AsmINT(ValImmU(8, 0x03))); ListAdd(PackAsm->Asms, lbl2); } - */ #endif ListAdd(PackAsm->Asms, AsmCMP(ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00), ValImmU(8, 0x00))); ListAdd(PackAsm->Asms, AsmJNE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True)))); From 3e7f1c043de0df1d051fa2c423e55a247af418e3 Mon Sep 17 00:00:00 2001 From: kuina Date: Mon, 11 Jun 2018 07:14:27 +0900 Subject: [PATCH 08/19] A trivial change. --- src/kuin_editor/form.kn | 7 +++++++ src/lib_wnd/main.cpp | 27 +++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/kuin_editor/form.kn b/src/kuin_editor/form.kn index bc5f0b21..d7a62a98 100644 --- a/src/kuin_editor/form.kn +++ b/src/kuin_editor/form.kn @@ -25,6 +25,7 @@ var popupMainHelp: wnd@Popup var lockingEditor: bool var lockPropOnChange: bool +var lockTreeItemOnSel: bool var textLog: []char var drag: bool @@ -116,6 +117,7 @@ var drag: bool do @lockingEditor :: false do @lockPropOnChange :: false + do @lockTreeItemOnSel :: false do @textLog :: "" do @drag :: false end func @@ -397,6 +399,9 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int) end func func treeItemOnSel(wnd: wnd@WndBase) + if(@lockTreeItemOnSel) + ret + end if do \src@curDoc.treeItemOnSel() end func @@ -693,11 +698,13 @@ end func end func +func updateTree() + do @lockTreeItemOnSel :: true do @treeItem.setRedraw(false) do @treeItem.clear() do \src@curDoc.updateTree(@treeItem) do @treeItem.expand(true) do @treeItem.setRedraw(true) + do @lockTreeItemOnSel :: false end func +func updateList() diff --git a/src/lib_wnd/main.cpp b/src/lib_wnd/main.cpp index c2752025..6cf58937 100644 --- a/src/lib_wnd/main.cpp +++ b/src/lib_wnd/main.cpp @@ -1586,14 +1586,7 @@ EXPORT_CPP void _treeMultiSetSel(SClass* me_, void* nodes) if (i == 0) TreeView_Select(me2->WndHandle, node2->Item, TVGN_CARET); else - { - TVITEM ti; - ti.mask = TVIF_STATE; - ti.hItem = node2->Item; - ti.state = LVIS_SELECTED; - ti.stateMask = LVIS_SELECTED; - TreeView_SetItem(me2->WndHandle, &ti); - } + TreeView_SetItemState(me2->WndHandle, node2->Item, TVIS_SELECTED, TVIS_SELECTED); } } @@ -2278,8 +2271,22 @@ static void CommandAndNotify(HWND wnd, UINT msg, WPARAM w_param, LPARAM l_param) } break; case TVN_SELCHANGED: - if (tree->OnSel != NULL) - Call1Asm(IncWndRef(reinterpret_cast(wnd_ctrl2)), tree->OnSel); + if (wnd_ctrl2->Kind == WndKind_Tree) + { + if (tree->OnSel != NULL) + Call1Asm(IncWndRef(reinterpret_cast(wnd_ctrl2)), tree->OnSel); + } + break; + case TVN_ITEMCHANGED: + if (wnd_ctrl2->Kind == WndKind_TreeMulti) + { + if (tree->OnSel != NULL) + { + NMTVITEMCHANGE* param = reinterpret_cast(l_param); + if ((param->uStateOld & TVIS_SELECTED) != (param->uStateNew & TVIS_SELECTED)) + Call1Asm(IncWndRef(reinterpret_cast(wnd_ctrl2)), tree->OnSel); + } + } break; } } From a087fc068ea7d4ca7268680de7b3ad39fd929e78 Mon Sep 17 00:00:00 2001 From: kuina Date: Wed, 13 Jun 2018 06:31:40 +0900 Subject: [PATCH 09/19] A trivial change. --- src/kuin_editor/doc_ar.kn | 60 +++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/src/kuin_editor/doc_ar.kn b/src/kuin_editor/doc_ar.kn index 18ccd0af..51956252 100644 --- a/src/kuin_editor/doc_ar.kn +++ b/src/kuin_editor/doc_ar.kn @@ -61,6 +61,9 @@ +*func draw(width: int, height: int) do draw@rect(0.0, 0.0, width $ float, height $ float, \common@colorBack) do drawRecursion(me.obj2dRoot, me.pageX, me.pageY, me.holds) + if(me.mode = %select) + do draw@rectLine((me.holdOffsetX - me.pageX) $ float, (me.holdOffsetY - me.pageY) $ float, (me.selectOffsetX - me.holdOffsetX) $ float, (me.selectOffsetY - me.holdOffsetY) $ float, 0xFF6666FF) + end if func drawRecursion(obj: @Obj2d, pageX: int, pageY: int, holds: list<@Obj2d>) do holds.head() @@ -94,17 +97,19 @@ end func +*func updateTree(tree: wnd@TreeMulti) - do updateTreeRecursion(me.holds, tree, tree.root(), me.obj2dRoot) + var sels: list :: #list + do updateTreeRecursion(me.holds, tree.root(), me.obj2dRoot, sels) + do tree.setSel(sels.toArray()) - func updateTreeRecursion(holds: list<@Obj2d>, tree: wnd@TreeMulti, node: wnd@TreeNode, obj: @Obj2d) + func updateTreeRecursion(holds: list<@Obj2d>, node: wnd@TreeNode, obj: @Obj2d, sels: list) var node2: wnd@TreeNode :: node.addChild(obj.objName) do holds.head() if(holds.find(obj)) - do tree.setSel([node2]) + do sels.add(node2) end if do obj.children.head() while(!obj.children.term()) - do updateTreeRecursion(holds, tree, node2, obj.children.get()) + do updateTreeRecursion(holds, node2, obj.children.get(), sels) do obj.children.next() end while end func @@ -260,7 +265,11 @@ do me.holdOffsetX :: obj.absX + obj.width - x2 do me.holdOffsetY :: obj.absY + obj.height - y2 elif(obj =& me.obj2dRoot) - do me.mode :: %none + do me.mode :: %select + do me.holdOffsetX :: x2 + do me.holdOffsetY :: y2 + do me.selectOffsetX :: x2 + do me.selectOffsetY :: y2 else do me.mode :: %move do me.holdOffsetX :: obj.absX - x2 @@ -348,7 +357,39 @@ do \form@updateTree() do \form@updateProp() do \form@paintDrawEditor() + case %select + var x1: int :: me.holdOffsetX + var y1: int :: me.holdOffsetY + var x2: int :: x + me.pageX + var y2: int :: y + me.pageY + if(x1 > x2) + do x1 :$ x2 + end if + if(y1 > y2) + do y1 :$ y2 + end if + do me.holds :: #list<@Obj2d> + do selRecursion(me.obj2dRoot, me.obj2dRoot, x1, y1, x2, y2, me.holds) + if(^me.holds = 0) + do me.holds.add(me.obj2dRoot) + end if + do me.mode :: %none + do \form@updateTree() + do \form@updateProp() + do \form@paintDrawEditor() end switch + + func selRecursion(root: @Obj2d, obj: @Obj2d, x: int, y: int, x2: int, y2: int, sels: list<@Obj2d>) + var result: @Obj2d :: null + if(obj <>& root & obj.absX <= x2 & x <= obj.absX + obj.width & obj.absY <= y2 & y <= obj.absY + obj.height) + do sels.add(obj) + end if + do obj.children.head() + while(!obj.children.term()) + do selRecursion(root, obj.children.get(), x, y, x2, y2, sels) + do obj.children.next() + end while + end func end func +*func mouseDoubleClick(x: int, y: int) @@ -378,6 +419,10 @@ end if do me.resizeObj2d(x + me.pageX, y + me.pageY) do \form@paintDrawEditor() + case %select + do me.selectOffsetX :: x + me.pageX + do me.selectOffsetY :: y + me.pageY + do \form@paintDrawEditor() end switch end func @@ -446,6 +491,8 @@ ret %move case %resize ret %resizeLTRD + case %select + ret %cross default assert false end switch @@ -519,6 +566,7 @@ put move resize + select end enum var src: [][]char @@ -532,6 +580,8 @@ var holdOffsetY: int var scrollOffsetX: int var scrollOffsetY: int + var selectOffsetX: int + var selectOffsetY: int +func makeObj2d(name: []char): @Obj2d end func From 480597706e20dc038ae92a21c894fbabf608dd4e Mon Sep 17 00:00:00 2001 From: kuina Date: Thu, 14 Jun 2018 07:50:56 +0900 Subject: [PATCH 10/19] A trivial change. --- src/kuin_editor/doc_ar.kn | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/kuin_editor/doc_ar.kn b/src/kuin_editor/doc_ar.kn index 51956252..08b2c00f 100644 --- a/src/kuin_editor/doc_ar.kn +++ b/src/kuin_editor/doc_ar.kn @@ -260,24 +260,25 @@ do obj :: me.obj2dRoot end if + do me.holdOffsetX :: x2 + do me.holdOffsetY :: y2 if(obj.absX + obj.width - resizeArea <= x2 & obj.absY + obj.height - resizeArea <= y2) do me.mode :: %resize - do me.holdOffsetX :: obj.absX + obj.width - x2 - do me.holdOffsetY :: obj.absY + obj.height - y2 elif(obj =& me.obj2dRoot) do me.mode :: %select - do me.holdOffsetX :: x2 - do me.holdOffsetY :: y2 do me.selectOffsetX :: x2 do me.selectOffsetY :: y2 else do me.mode :: %move - do me.holdOffsetX :: obj.absX - x2 - do me.holdOffsetY :: obj.absY - y2 end if - do me.holds :: #list<@Obj2d> - do me.holds.add(obj) + var found: bool :: me.holds.find(obj) + if(!wnd@key(%shift) & !wnd@key(%ctrl) & !found) + do me.holds :: #list<@Obj2d> + end if + if(!found) + do me.holds.add(obj) + end if else if (\form@getLockingEditor()) do \form@showMsgRunning() @@ -285,8 +286,8 @@ end if var name: []char :: \form@listInfo.getText(me.ctrl) do me.mode :: %put - do me.holdOffsetX :: 0 - do me.holdOffsetY :: 0 + do me.holdOffsetX :: x2 + do me.holdOffsetY :: y2 var obj: @Obj2d :: me.makeObj2d(name) var minWidth: int var minHeight: int @@ -404,6 +405,8 @@ ret end if do me.resizeObj2d(x + me.pageX, y + me.pageY) + do me.holdOffsetX :: x + me.pageX + do me.holdOffsetY :: y + me.pageY do \form@paintDrawEditor() case %move if (\form@getLockingEditor()) @@ -411,6 +414,8 @@ ret end if do me.moveObj2d(x + me.pageX, y + me.pageY) + do me.holdOffsetX :: x + me.pageX + do me.holdOffsetY :: y + me.pageY do \form@paintDrawEditor() case %resize if (\form@getLockingEditor()) @@ -418,6 +423,8 @@ ret end if do me.resizeObj2d(x + me.pageX, y + me.pageY) + do me.holdOffsetX :: x + me.pageX + do me.holdOffsetY :: y + me.pageY do \form@paintDrawEditor() case %select do me.selectOffsetX :: x + me.pageX @@ -630,8 +637,8 @@ do me.holds.head() while(!me.holds.term()) var obj: @Obj2d :: me.holds.get() - var width: int :: x - obj.absX + me.holdOffsetX - var height: int :: y - obj.absY + me.holdOffsetY + var width: int :: obj.width + x - me.holdOffsetX + var height: int :: obj.height + y - me.holdOffsetY var minWidth: int var minHeight: int var maxWidth: int @@ -659,8 +666,8 @@ do me.holds.head() while(!me.holds.term()) var obj: @Obj2d :: me.holds.get() - do obj.absX :: x + me.holdOffsetX - do obj.absY :: y + me.holdOffsetY + do obj.absX :+ x - me.holdOffsetX + do obj.absY :+ y - me.holdOffsetY do me.stick(&obj.absX, &obj.absY) do me.holds.next() end while From c2882ca79b2144163834cabd7ce6cf57d6ca96a4 Mon Sep 17 00:00:00 2001 From: kuina Date: Fri, 15 Jun 2018 12:52:26 +0900 Subject: [PATCH 11/19] A trivial change. --- src/kuin_editor/doc_ar.kn | 11 ++++++----- src/lib_wnd/main.cpp | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kuin_editor/doc_ar.kn b/src/kuin_editor/doc_ar.kn index 08b2c00f..14e5a353 100644 --- a/src/kuin_editor/doc_ar.kn +++ b/src/kuin_editor/doc_ar.kn @@ -256,15 +256,12 @@ var y2: int :: y + me.pageY if(me.ctrl <= 0) var obj: @Obj2d :: selRecursion(me.obj2dRoot, x2, y2) - if(obj =& null) - do obj :: me.obj2dRoot - end if do me.holdOffsetX :: x2 do me.holdOffsetY :: y2 - if(obj.absX + obj.width - resizeArea <= x2 & obj.absY + obj.height - resizeArea <= y2) + if(obj <>& null & obj.absX + obj.width - resizeArea <= x2 & obj.absY + obj.height - resizeArea <= y2) do me.mode :: %resize - elif(obj =& me.obj2dRoot) + elif(obj =& null | obj =& me.obj2dRoot) do me.mode :: %select do me.selectOffsetX :: x2 do me.selectOffsetY :: y2 @@ -272,6 +269,10 @@ do me.mode :: %move end if + if(obj =& null) + do obj :: me.obj2dRoot + end if + var found: bool :: me.holds.find(obj) if(!wnd@key(%shift) & !wnd@key(%ctrl) & !found) do me.holds :: #list<@Obj2d> diff --git a/src/lib_wnd/main.cpp b/src/lib_wnd/main.cpp index 6cf58937..db7ca022 100644 --- a/src/lib_wnd/main.cpp +++ b/src/lib_wnd/main.cpp @@ -1512,7 +1512,6 @@ EXPORT_CPP SClass* _makeTreeMulti(SClass* me_, SClass* parent, S64 x, S64 y, S64 { STree* me2 = reinterpret_cast(me_); SetCtrlParam(reinterpret_cast(me_), reinterpret_cast(parent), WndKind_TreeMulti, WC_TREEVIEW, WS_EX_CLIENTEDGE, WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_LINESATROOT, x, y, width, height, L"", WndProcTree, anchorX, anchorY); - TreeView_SetExtendedStyle(reinterpret_cast(me2)->WndHandle, TVS_EX_MULTISELECT, TVS_EX_MULTISELECT); reinterpret_cast(me2)->Draggable = False; reinterpret_cast(me2)->AllowDraggingToRoot = False; reinterpret_cast(me2)->DraggingItem = NULL; From 6627e367292286d600a58924a888e9a983026fab Mon Sep 17 00:00:00 2001 From: kuina Date: Fri, 15 Jun 2018 14:53:13 +0900 Subject: [PATCH 12/19] Add 'math@knapsack' function. --- package/sys/math.kn | 3 +++ src/lib_math/main.c | 35 +++++++++++++++++++++++++++++++++++ src/lib_math/main.h | 1 + test/correct/log0021.txt | 3 +++ test/kn/test.kn | 3 +++ test/kn/test0021.kn | 4 ++++ 6 files changed, 49 insertions(+) diff --git a/package/sys/math.kn b/package/sys/math.kn index fa6b6ec2..15f23000 100644 --- a/package/sys/math.kn +++ b/package/sys/math.kn @@ -28,6 +28,9 @@ end func +func [d0003.knd, _factInt] factInt(n: int): int end func ++func [d0003.knd, _knapsack] knapsack(weights: []int, values: []int, maxWeight: int): int +end func + +class Mat() *func [d0003.knd, _matDtor, _force] _dtor() end func diff --git a/src/lib_math/main.c b/src/lib_math/main.c index 0ccaa665..a4ab80e3 100644 --- a/src/lib_math/main.c +++ b/src/lib_math/main.c @@ -260,6 +260,41 @@ EXPORT S64 _factInt(S64 n) return Facts[n]; } +EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight) +{ + THROWDBG(weights == NULL || values == NULL, 0xc0000005); + THROWDBG(*(S64*)((U8*)weights + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006); + S64 len = *(S64*)((U8*)weights + 0x08); + const S64* weights2 = (S64*)((U8*)weights + 0x10); + const S64* values2 = (S64*)((U8*)values + 0x10); + S64* dp = (S64*)AllocMem(sizeof(S64) * (size_t)((max_weight + 1) * 2)); + S64* dp_a = dp; + S64* dp_b = dp + (max_weight + 1); + S64 i, j; + memset(dp_a, 0, sizeof(S64) * (size_t)(max_weight + 1)); + for (i = 0; i < len; i++) + { + for (j = 0; j <= max_weight; j++) + { + if (j < weights2[i]) + dp_b[j] = dp_a[j]; + else + { + S64 value = dp_a[j - weights2[i]] + values2[i]; + dp_b[j] = dp_a[j] < value ? value : dp_a[j]; + } + } + { + S64* tmp = dp_a; + dp_a = dp_b; + dp_b = tmp; + } + } + S64 result = dp_a[max_weight]; + FreeMem(dp); + return result; +} + EXPORT SClass* _makeMat(SClass* me_, S64 row, S64 col) { THROWDBG(row <= 0 || col <= 0, 0xe9170006); diff --git a/src/lib_math/main.h b/src/lib_math/main.h index fae1c325..be416d99 100644 --- a/src/lib_math/main.h +++ b/src/lib_math/main.h @@ -13,5 +13,6 @@ EXPORT void* _primeFactors(S64 n); EXPORT double _gamma(double n); EXPORT double _fact(double n); EXPORT S64 _factInt(S64 n); +EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight); EXPORT SClass* _makeMat(SClass* me_, S64 row, S64 col); EXPORT void _matDtor(SClass* me_); diff --git a/test/correct/log0021.txt b/test/correct/log0021.txt index f583cb61..4eb506b4 100644 --- a/test/correct/log0021.txt +++ b/test/correct/log0021.txt @@ -6,16 +6,19 @@ Excpt: 80000003 > 3 > Not found. > Not found. +> 7 > 3 > 5 > Not found. > 3 > Not found. > Not found. +> 7 > 3 > 5 > Not found. > 3 > Not found. > Not found. +> 7 end: ../../test/output/output0021.exe diff --git a/test/kn/test.kn b/test/kn/test.kn index e69de29b..6a9fed6e 100644 --- a/test/kn/test.kn +++ b/test/kn/test.kn @@ -0,0 +1,3 @@ +func main() + do cui@print(math@knapsack([2, 1, 3, 2], [3, 2, 4, 2], 100).toStr() ~ "\n") +end func diff --git a/test/kn/test0021.kn b/test/kn/test0021.kn index e3d093cc..f3fc0d42 100644 --- a/test/kn/test0021.kn +++ b/test/kn/test0021.kn @@ -37,5 +37,9 @@ func main() do cui@print("Not found.") end if end block + + block + do cui@print(math@knapsack([2, 1, 3, 2], [3, 2, 4, 2], 5).toStr()) + end block end for end func From 43a984cb4f46c48e34563825114d9bebe70bebd1 Mon Sep 17 00:00:00 2001 From: kuina Date: Fri, 15 Jun 2018 14:54:41 +0900 Subject: [PATCH 13/19] A trivial change. --- package/readme.txt | 1 + test/kn/test.kn | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package/readme.txt b/package/readme.txt index b0bc2b2c..ee786899 100644 --- a/package/readme.txt +++ b/package/readme.txt @@ -50,6 +50,7 @@ v.2018.6.17 - 16進数リテラルの構文を「16#」から「0x」に変更 - 細かな機能追加 - list.find、list.findLastメソッドの追加 + - math@knapsack関数の追加 v.2018.5.17 - 輪郭線を描画するメソッドdraw@Obj.drawOutlineの追加 diff --git a/test/kn/test.kn b/test/kn/test.kn index 6a9fed6e..e69de29b 100644 --- a/test/kn/test.kn +++ b/test/kn/test.kn @@ -1,3 +0,0 @@ -func main() - do cui@print(math@knapsack([2, 1, 3, 2], [3, 2, 4, 2], 100).toStr() ~ "\n") -end func From 3f54be8b10a83f71739d45bd0dd1d348f9c08423 Mon Sep 17 00:00:00 2001 From: kuina Date: Fri, 15 Jun 2018 16:41:23 +0900 Subject: [PATCH 14/19] A trivial change. --- package/sys/math.kn | 2 +- src/lib_math/main.c | 36 ++++++++++++++++++++---------------- src/lib_math/main.h | 2 +- test/correct/log0021.txt | 3 +++ test/kn/test0021.kn | 3 ++- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/package/sys/math.kn b/package/sys/math.kn index 15f23000..73248bf0 100644 --- a/package/sys/math.kn +++ b/package/sys/math.kn @@ -28,7 +28,7 @@ end func +func [d0003.knd, _factInt] factInt(n: int): int end func -+func [d0003.knd, _knapsack] knapsack(weights: []int, values: []int, maxWeight: int): int ++func [d0003.knd, _knapsack] knapsack(weights: []int, values: []int, maxWeight: int, reuse: bool): int end func +class Mat() diff --git a/src/lib_math/main.c b/src/lib_math/main.c index a4ab80e3..30033afa 100644 --- a/src/lib_math/main.c +++ b/src/lib_math/main.c @@ -260,37 +260,41 @@ EXPORT S64 _factInt(S64 n) return Facts[n]; } -EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight) +EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bool reuse) { THROWDBG(weights == NULL || values == NULL, 0xc0000005); THROWDBG(*(S64*)((U8*)weights + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006); S64 len = *(S64*)((U8*)weights + 0x08); const S64* weights2 = (S64*)((U8*)weights + 0x10); const S64* values2 = (S64*)((U8*)values + 0x10); - S64* dp = (S64*)AllocMem(sizeof(S64) * (size_t)((max_weight + 1) * 2)); - S64* dp_a = dp; - S64* dp_b = dp + (max_weight + 1); + S64* dp = (S64*)AllocMem(sizeof(S64) * (size_t)(max_weight + 1)); S64 i, j; - memset(dp_a, 0, sizeof(S64) * (size_t)(max_weight + 1)); - for (i = 0; i < len; i++) + memset(dp, 0, sizeof(S64) * (size_t)(max_weight + 1)); + if (reuse) { - for (j = 0; j <= max_weight; j++) + for (i = 0; i < len; i++) { - if (j < weights2[i]) - dp_b[j] = dp_a[j]; - else + for (j = weights2[i]; j <= max_weight; j++) { - S64 value = dp_a[j - weights2[i]] + values2[i]; - dp_b[j] = dp_a[j] < value ? value : dp_a[j]; + S64 value = dp[j - weights2[i]] + values2[i]; + if (dp[j] < value) + dp[j] = value; } } + } + else + { + for (i = 0; i < len; i++) { - S64* tmp = dp_a; - dp_a = dp_b; - dp_b = tmp; + for (j = max_weight; j >= weights2[i]; j--) + { + S64 value = dp[j - weights2[i]] + values2[i]; + if (dp[j] < value) + dp[j] = value; + } } } - S64 result = dp_a[max_weight]; + S64 result = dp[max_weight]; FreeMem(dp); return result; } diff --git a/src/lib_math/main.h b/src/lib_math/main.h index be416d99..c9cc01cf 100644 --- a/src/lib_math/main.h +++ b/src/lib_math/main.h @@ -13,6 +13,6 @@ EXPORT void* _primeFactors(S64 n); EXPORT double _gamma(double n); EXPORT double _fact(double n); EXPORT S64 _factInt(S64 n); -EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight); +EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bool reuse); EXPORT SClass* _makeMat(SClass* me_, S64 row, S64 col); EXPORT void _matDtor(SClass* me_); diff --git a/test/correct/log0021.txt b/test/correct/log0021.txt index 4eb506b4..c22f04f3 100644 --- a/test/correct/log0021.txt +++ b/test/correct/log0021.txt @@ -7,6 +7,7 @@ Excpt: 80000003 > Not found. > Not found. > 7 +> 10 > 3 > 5 > Not found. @@ -14,6 +15,7 @@ Excpt: 80000003 > Not found. > Not found. > 7 +> 10 > 3 > 5 > Not found. @@ -21,4 +23,5 @@ Excpt: 80000003 > Not found. > Not found. > 7 +> 10 end: ../../test/output/output0021.exe diff --git a/test/kn/test0021.kn b/test/kn/test0021.kn index f3fc0d42..f95de42a 100644 --- a/test/kn/test0021.kn +++ b/test/kn/test0021.kn @@ -39,7 +39,8 @@ func main() end block block - do cui@print(math@knapsack([2, 1, 3, 2], [3, 2, 4, 2], 5).toStr()) + do cui@print(math@knapsack([2, 1, 3, 2], [3, 2, 4, 2], 5, false).toStr()) + do cui@print(math@knapsack([3, 4, 2], [4, 5, 3], 7, true).toStr()) end block end for end func From 0ccb63372be5a57a6af54bd145351b43c2a3194b Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 16 Jun 2018 06:22:08 +0900 Subject: [PATCH 15/19] A trivial change. --- src/lib_math/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib_math/main.c b/src/lib_math/main.c index 30033afa..28d9a5c0 100644 --- a/src/lib_math/main.c +++ b/src/lib_math/main.c @@ -269,6 +269,10 @@ EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bo const S64* values2 = (S64*)((U8*)values + 0x10); S64* dp = (S64*)AllocMem(sizeof(S64) * (size_t)(max_weight + 1)); S64 i, j; +#if defined(DBG) + for (i = 0; i < len; i++) + THROWDBG(weights2[i] <= 0, 0xe9170006); +#endif memset(dp, 0, sizeof(S64) * (size_t)(max_weight + 1)); if (reuse) { From b8025d4600609760e2d86a3c8000e6d6ac40625d Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 16 Jun 2018 12:40:14 +0900 Subject: [PATCH 16/19] Add 'draw@filterMonotone' function. --- package/sys/draw.kn | 6 +++ src/common.c | 7 +-- src/common.h | 8 ++- src/lib_wnd/draw.cpp | 50 ++++++++++++++++--- src/lib_wnd/draw.h | 2 + src/lib_wnd/filter_monotone_ps.c | 40 +++++++++++++++ src/lib_wnd/{filter_ps.c => filter_none_ps.c} | 6 +-- src/lib_wnd/lib_wnd.vcxproj | 3 +- src/lib_wnd/lib_wnd.vcxproj.filters | 3 +- src/shaders/build.bat | 3 +- src/shaders/filter_monotone_ps.fx | 23 +++++++++ .../{filter_ps.fx => filter_none_ps.fx} | 0 12 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 src/lib_wnd/filter_monotone_ps.c rename src/lib_wnd/{filter_ps.c => filter_none_ps.c} (96%) create mode 100644 src/shaders/filter_monotone_ps.fx rename src/shaders/{filter_ps.fx => filter_none_ps.fx} (100%) diff --git a/package/sys/draw.kn b/package/sys/draw.kn index caf2a01d..4d58ac79 100644 --- a/package/sys/draw.kn +++ b/package/sys/draw.kn @@ -56,6 +56,12 @@ end func +func [d0001.knd, _circle, _1] circle(x: float, y: float, radiusX: float, radiusY: float, color: int) end func ++func [d0001.knd, _filterNone] filterNone() +end func + ++func [d0001.knd, _filterMonotone, _2] filterMonotone(color: int, rate: float) +end func + +class Tex() *func [d0001.knd, _texDtor, _force] _dtor() end func diff --git a/src/common.c b/src/common.c index 7284a332..d5d43b98 100644 --- a/src/common.c +++ b/src/common.c @@ -25,10 +25,6 @@ void* Heap; S64* HeapCnt; S64 AppCode; const U8* UseResFlags; -/* - UseResFlags: - 1 = draw@circle -*/ HINSTANCE Instance; #if !defined(DBG) @@ -302,8 +298,9 @@ U8* Utf8ToUtf16(const char* str) return buf; } -Bool IsResUsed(S64 idx) +Bool IsResUsed(EUseResFlagsKind kind) { + S64 idx = (S64)kind; ASSERT(1 <= idx && (idx - 1) / 8 < USE_RES_FLAGS_LEN); return (UseResFlags[(idx - 1) / 8] & (1 << ((idx - 1) % 8))) != 0; } diff --git a/src/common.h b/src/common.h index 9898b8a0..d8183d5e 100644 --- a/src/common.h +++ b/src/common.h @@ -71,7 +71,13 @@ static const S64 DefaultRefCntOpe = 1; // For 'GcInstance'. static void* DummyPtr = (void*)1i64; // An invalid pointer used to point to non-NULL. +typedef enum EUseResFlagsKind +{ + UseResFlagsKind_Draw_Circle = 1, + UseResFlagsKind_Draw_FilterMonotone = 2, +} EUseResFlagsKind; #define USE_RES_FLAGS_LEN (1) + extern void* Heap; extern S64* HeapCnt; extern S64 AppCode; @@ -96,7 +102,7 @@ Bool IsPowerOf2(U64 n); U32 XorShift(U32* seed); char* Utf16ToUtf8(const U8* str); U8* Utf8ToUtf16(const char* str); -Bool IsResUsed(S64 idx); +Bool IsResUsed(EUseResFlagsKind kind); #define THROW(code) ThrowImpl(code) #if defined(DBG) diff --git a/src/lib_wnd/draw.cpp b/src/lib_wnd/draw.cpp index cfd53ff9..29d2ddac 100644 --- a/src/lib_wnd/draw.cpp +++ b/src/lib_wnd/draw.cpp @@ -17,6 +17,7 @@ static const int JointMax = 256; static const int FontBitmapSize = 1024; static const int TexEvenNum = 3; static const double DiscardAlpha = 0.02; +static const int FilterNum = 2; struct SWndBuf { @@ -159,7 +160,8 @@ const U8* GetObjOutlineVsBin(size_t* size); const U8* GetObjOutlineJointVsBin(size_t* size); const U8* GetObjOutlinePsBin(size_t* size); const U8* GetFilterVsBin(size_t* size); -const U8* GetFilterPsBin(size_t* size); +const U8* GetFilterNonePsBin(size_t* size); +const U8* GetFilterMonotonePsBin(size_t* size); const U8* GetToonRampPngBin(size_t* size); static S64 Cnt; @@ -194,7 +196,7 @@ static void* ObjOutlineJointVs = NULL; static void* ObjOutlinePs = NULL; static void* FilterVertex = NULL; static void* FilterVs = NULL; -static void* FilterPs = NULL; +static void* FilterPs[FilterNum] = { NULL }; static double ViewMat[4][4]; static double ProjMat[4][4]; static SObjVsConstBuf ObjVsConstBuf; @@ -206,6 +208,8 @@ ID3D10Texture2D* TexToonRamp; ID3D10ShaderResourceView* ViewToonRamp; ID3D10Texture2D* TexEven[TexEvenNum]; ID3D10ShaderResourceView* ViewEven[TexEvenNum]; +static int FilterIdx = 0; +static float FilterParam[4][4]; EXPORT_CPP void _render(S64 fps) { @@ -223,7 +227,7 @@ EXPORT_CPP void _render(S64 fps) { Draw::ConstBuf(FilterVs, NULL); Device->GSSetShader(NULL); - Draw::ConstBuf(FilterPs, NULL); + Draw::ConstBuf(FilterPs[FilterIdx], FilterParam); Draw::VertexBuf(FilterVertex); Device->PSSetShaderResources(0, 1, &CurWndBuf->TmpShaderResView); } @@ -535,6 +539,27 @@ EXPORT_CPP void _circle(double x, double y, double radiusX, double radiusY, S64 Device->DrawIndexed(6, 0, 0); } +EXPORT_CPP void _filterNone() +{ + FilterIdx = 0; +} + +EXPORT_CPP void _filterMonotone(S64 color, double rate) +{ + double r, g, b, a; + Draw::ColorToArgb(&a, &r, &g, &b, color); + if (rate < 0.0) + rate = 0.0; + else if (rate > 1.0) + rate = 1.0; + + FilterIdx = 1; + FilterParam[0][0] = static_cast(r); + FilterParam[0][1] = static_cast(g); + FilterParam[0][2] = static_cast(b); + FilterParam[0][3] = static_cast(rate); +} + EXPORT_CPP SClass* _makeTex(SClass* me_, const U8* path) { return Draw::MakeTexImpl(me_, path, False); @@ -1801,7 +1826,7 @@ void Init() } // Initialize 'Circle'. - if (IsResUsed(1)) + if (IsResUsed(UseResFlagsKind_Draw_Circle)) { { float vertices[] = @@ -2042,8 +2067,14 @@ void Init() } { size_t size; - const U8* bin = GetFilterPsBin(&size); - FilterPs = MakeShaderBuf(ShaderKind_Ps, size, bin, 0, 0, NULL, NULL); + const U8* bin = GetFilterNonePsBin(&size); + FilterPs[0] = MakeShaderBuf(ShaderKind_Ps, size, bin, 0, 0, NULL, NULL); + } + if (IsResUsed(UseResFlagsKind_Draw_FilterMonotone)) + { + size_t size; + const U8* bin = GetFilterMonotonePsBin(&size); + FilterPs[1] = MakeShaderBuf(ShaderKind_Ps, size, bin, sizeof(float) * 4, 0, NULL, NULL); } } } @@ -2190,8 +2221,11 @@ void Fin() ViewToonRamp->Release(); if (TexToonRamp != NULL) TexToonRamp->Release(); - if (FilterPs != NULL) - FinShaderBuf(FilterPs); + for (int i = 0; i < FilterNum; i++) + { + if (FilterPs[i] != NULL) + FinShaderBuf(FilterPs[i]); + } if (FilterVs != NULL) FinShaderBuf(FilterVs); if (FilterVertex != NULL) diff --git a/src/lib_wnd/draw.h b/src/lib_wnd/draw.h index 78a30c2f..9be243ee 100644 --- a/src/lib_wnd/draw.h +++ b/src/lib_wnd/draw.h @@ -15,6 +15,8 @@ EXPORT_CPP void _tri(double x1, double y1, double x2, double y2, double x3, doub EXPORT_CPP void _rect(double x, double y, double w, double h, S64 color); EXPORT_CPP void _rectLine(double x, double y, double w, double h, S64 color); EXPORT_CPP void _circle(double x, double y, double radiusX, double radiusY, S64 color); +EXPORT_CPP void _filterNone(); +EXPORT_CPP void _filterMonotone(S64 color, double rate); EXPORT_CPP SClass* _makeTex(SClass* me_, const U8* path); EXPORT_CPP SClass* _makeTexArgb(SClass* me_, const U8* path); EXPORT_CPP SClass* _makeTexEvenArgb(SClass* me_, double a, double r, double g, double b); diff --git a/src/lib_wnd/filter_monotone_ps.c b/src/lib_wnd/filter_monotone_ps.c new file mode 100644 index 00000000..d307f2d9 --- /dev/null +++ b/src/lib_wnd/filter_monotone_ps.c @@ -0,0 +1,40 @@ +#include "../common.h" + +const U8* GetFilterMonotonePsBin(size_t* size) +{ + static const U8 filter_monotone_ps_bin[0x0000039c] = + { + 0x44, 0x58, 0x42, 0x43, 0xbb, 0xac, 0xfa, 0x06, 0x3b, 0xf1, 0xa3, 0xc5, 0x3a, 0x2f, 0x00, 0x1e, 0x41, 0x9c, 0xae, 0x3b, 0x01, 0x00, 0x00, 0x00, 0x9c, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, + 0x49, 0x6d, 0x67, 0x00, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x42, 0x75, 0x66, 0x00, 0xab, 0xab, 0xab, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, + 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, + 0x00, 0xab, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x40, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0xfe, 0x0a, 0x99, 0x3e, 0x23, 0x2c, 0x16, 0x3f, 0x71, 0x73, 0xea, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x80, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x38, 0x00, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf6, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, + 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + *size = 0x0000039c; + return filter_monotone_ps_bin; +} diff --git a/src/lib_wnd/filter_ps.c b/src/lib_wnd/filter_none_ps.c similarity index 96% rename from src/lib_wnd/filter_ps.c rename to src/lib_wnd/filter_none_ps.c index 25e325f7..b5cad7fb 100644 --- a/src/lib_wnd/filter_ps.c +++ b/src/lib_wnd/filter_none_ps.c @@ -1,8 +1,8 @@ #include "../common.h" -const U8* GetFilterPsBin(size_t* size) +const U8* GetFilterNonePsBin(size_t* size) { - static const U8 filter_ps_bin[0x0000024c] = + static const U8 filter_none_ps_bin[0x0000024c] = { 0x44, 0x58, 0x42, 0x43, 0xf6, 0xbf, 0xb0, 0x0d, 0x35, 0xd8, 0x87, 0x27, 0x8c, 0x6e, 0x78, 0xa8, 0xb7, 0x25, 0xe2, 0x75, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -26,5 +26,5 @@ const U8* GetFilterPsBin(size_t* size) }; *size = 0x0000024c; - return filter_ps_bin; + return filter_none_ps_bin; } diff --git a/src/lib_wnd/lib_wnd.vcxproj b/src/lib_wnd/lib_wnd.vcxproj index a69052c7..8a7a053b 100644 --- a/src/lib_wnd/lib_wnd.vcxproj +++ b/src/lib_wnd/lib_wnd.vcxproj @@ -148,7 +148,8 @@ - + + diff --git a/src/lib_wnd/lib_wnd.vcxproj.filters b/src/lib_wnd/lib_wnd.vcxproj.filters index d4a0a127..b674313a 100644 --- a/src/lib_wnd/lib_wnd.vcxproj.filters +++ b/src/lib_wnd/lib_wnd.vcxproj.filters @@ -22,13 +22,14 @@ - + + diff --git a/src/shaders/build.bat b/src/shaders/build.bat index 083d3527..27e47004 100644 --- a/src/shaders/build.bat +++ b/src/shaders/build.bat @@ -17,5 +17,6 @@ set fxc_path="C:\Program Files (x86)\Windows Kits\8.1\bin\x64\fxc.exe" %fxc_path% obj_outline_vs.fx /T vs_4_0 /Fo obj_outline_joint.vs /DJOINT %fxc_path% obj_outline_ps.fx /T ps_4_0 /Fo obj_outline.ps %fxc_path% filter_vs.fx /T vs_4_0 /Fo filter.vs -%fxc_path% filter_ps.fx /T ps_4_0 /Fo filter.ps +%fxc_path% filter_none_ps.fx /T ps_4_0 /Fo filter_none.ps +%fxc_path% filter_monotone_ps.fx /T ps_4_0 /Fo filter_monotone.ps pause diff --git a/src/shaders/filter_monotone_ps.fx b/src/shaders/filter_monotone_ps.fx new file mode 100644 index 00000000..8fcee9c7 --- /dev/null +++ b/src/shaders/filter_monotone_ps.fx @@ -0,0 +1,23 @@ +cbuffer ConstBuf: register(b0) +{ + float4 Color; +}; + +Texture2D Img: register(t0); +SamplerState Sampler: register(s0); + +struct PS_INPUT +{ + float4 Pos: SV_POSITION; + float2 Tex: TEXCOORD; +}; + +float4 main(PS_INPUT input): SV_TARGET +{ + float4 tex_color = Img.Sample(Sampler, input.Tex); + float luminance = 0.298912f * tex_color.r + 0.586611f * tex_color.g + 0.114478f * tex_color.b; + float4 output; + output.rgb = luminance * float3(Color.rgb) * Color.a + tex_color.rgb * (1.0f - Color.a); + output.a = 1.0f; + return output; +} diff --git a/src/shaders/filter_ps.fx b/src/shaders/filter_none_ps.fx similarity index 100% rename from src/shaders/filter_ps.fx rename to src/shaders/filter_none_ps.fx From f2c1e597b9a251ddc2e3280b7e986d477fd8d8ef Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 16 Jun 2018 17:09:33 +0900 Subject: [PATCH 17/19] A trivial change. --- src/common.h | 2 +- src/lib_wnd/draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common.h b/src/common.h index d8183d5e..dbe12c5e 100644 --- a/src/common.h +++ b/src/common.h @@ -74,7 +74,7 @@ static void* DummyPtr = (void*)1i64; // An invalid pointer used to point to non- typedef enum EUseResFlagsKind { UseResFlagsKind_Draw_Circle = 1, - UseResFlagsKind_Draw_FilterMonotone = 2, + UseResFlagsKind_Draw_FilterMonotone, } EUseResFlagsKind; #define USE_RES_FLAGS_LEN (1) diff --git a/src/lib_wnd/draw.cpp b/src/lib_wnd/draw.cpp index 29d2ddac..c0664737 100644 --- a/src/lib_wnd/draw.cpp +++ b/src/lib_wnd/draw.cpp @@ -227,7 +227,7 @@ EXPORT_CPP void _render(S64 fps) { Draw::ConstBuf(FilterVs, NULL); Device->GSSetShader(NULL); - Draw::ConstBuf(FilterPs[FilterIdx], FilterParam); + Draw::ConstBuf(FilterPs[FilterIdx], FilterIdx == 0 ? NULL : FilterParam); Draw::VertexBuf(FilterVertex); Device->PSSetShaderResources(0, 1, &CurWndBuf->TmpShaderResView); } From fe3542d8aeab695187d7e3bb287ffe85438de5a4 Mon Sep 17 00:00:00 2001 From: kuina Date: Sat, 16 Jun 2018 18:31:09 +0900 Subject: [PATCH 18/19] A trivial change. --- package/readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/readme.txt b/package/readme.txt index ee786899..2b87a8ea 100644 --- a/package/readme.txt +++ b/package/readme.txt @@ -50,7 +50,7 @@ v.2018.6.17 - 16進数リテラルの構文を「16#」から「0x」に変更 - 細かな機能追加 - list.find、list.findLastメソッドの追加 - - math@knapsack関数の追加 + - math@knapsack、draw@filterNone、draw@filterMonotone関数の追加 v.2018.5.17 - 輪郭線を描画するメソッドdraw@Obj.drawOutlineの追加 From 72dd2c321780fdc21e065d2ae288ba8794304320 Mon Sep 17 00:00:00 2001 From: kuina Date: Sun, 17 Jun 2018 19:02:48 +0900 Subject: [PATCH 19/19] Add math functions. --- package/readme.txt | 3 +- package/sys/math.kn | 9 ++ src/lib_common/lib.c | 2 +- src/lib_math/main.c | 194 +++++++++++++++++++++++++++++++++++++++ src/lib_math/main.h | 3 + test/correct/log0021.txt | 63 +++++++++++++ test/kn/test0021.kn | 21 +++++ 7 files changed, 293 insertions(+), 2 deletions(-) diff --git a/package/readme.txt b/package/readme.txt index 2b87a8ea..1a5aab8b 100644 --- a/package/readme.txt +++ b/package/readme.txt @@ -50,7 +50,8 @@ v.2018.6.17 - 16進数リテラルの構文を「16#」から「0x」に変更 - 細かな機能追加 - list.find、list.findLastメソッドの追加 - - math@knapsack、draw@filterNone、draw@filterMonotone関数の追加 + - math@knapsack、math@dijkstra、math@bellmanFord、math@floydWarshall、 + draw@filterNone、draw@filterMonotone関数の追加 v.2018.5.17 - 輪郭線を描画するメソッドdraw@Obj.drawOutlineの追加 diff --git a/package/sys/math.kn b/package/sys/math.kn index 73248bf0..fc19c111 100644 --- a/package/sys/math.kn +++ b/package/sys/math.kn @@ -31,6 +31,15 @@ end func +func [d0003.knd, _knapsack] knapsack(weights: []int, values: []int, maxWeight: int, reuse: bool): int end func ++func [d0003.knd, _dijkstra] dijkstra(nodeNum: int, fromNodes: []int, toNodes: []int, values: []int, beginNode: int): []int +end func + ++func [d0003.knd, _bellmanFord] bellmanFord(nodeNum: int, fromNodes: []int, toNodes: []int, values: []int, beginNode: int): []int +end func + ++func [d0003.knd, _floydWarshall] floydWarshall(nodeNum: int, fromNodes: []int, toNodes: []int, values: []int): [][]int +end func + +class Mat() *func [d0003.knd, _matDtor, _force] _dtor() end func diff --git a/src/lib_common/lib.c b/src/lib_common/lib.c index 52a85f96..ba3c1f0c 100644 --- a/src/lib_common/lib.c +++ b/src/lib_common/lib.c @@ -20,7 +20,7 @@ EXPORT void* _cmdLine(void) { int i; void** ptr; - U8* result = (U8*)AllocMem(0x10 + sizeof(Char*) * (size_t)(num - 1)); + U8* result = (U8*)AllocMem(0x10 + sizeof(void**) * (size_t)(num - 1)); ((S64*)result)[0] = DefaultRefCntFunc; ((S64*)result)[1] = (S64)(num - 1); ptr = (void**)(result + 0x10); diff --git a/src/lib_math/main.c b/src/lib_math/main.c index 28d9a5c0..a1abe32d 100644 --- a/src/lib_math/main.c +++ b/src/lib_math/main.c @@ -303,6 +303,200 @@ EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bo return result; } +EXPORT void* _dijkstra(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node) +{ + THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, 0xc0000005); + THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006); + THROWDBG(node_num <= 0 || begin_node < 0 || node_num <= begin_node, 0xe9170006); + const S64* from_nodes2 = (S64*)((U8*)from_nodes + 0x10); + const S64* to_nodes2 = (S64*)((U8*)to_nodes + 0x10); + const S64* values2 = (S64*)((U8*)values + 0x10); + S64 len = *(S64*)((U8*)from_nodes + 0x08); + S64 i; +#if defined(DBG) + for (i = 0; i < len; i++) + THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i] || values2[i] < 0, 0xe9170006); +#endif + + U8* result = (U8*)AllocMem(0x10 + sizeof(S64) * (size_t)node_num); + ((S64*)result)[0] = DefaultRefCntFunc; + ((S64*)result)[1] = node_num; + S64* distance = (S64*)(result + 0x10); + for (i = 0; i < node_num; i++) + distance[i] = LLONG_MAX; + distance[begin_node] = 0; + + S64* heap = (S64*)AllocMem(sizeof(S64) * (2 * (size_t)(node_num * len) + 2)); + int heap_cnt = 1; + heap[0] = begin_node; + heap[1] = 0; + while (heap_cnt > 0) + { + S64 item_node = heap[0]; + S64 item_value = heap[1]; + heap_cnt--; + heap[0] = heap[heap_cnt * 2]; + heap[1] = heap[heap_cnt * 2 + 1]; + { + S64 del_idx = 0; + for (; ; ) + { + if ((del_idx + 1) * 2 - 1 < heap_cnt && heap[del_idx * 2 + 1] > heap[((del_idx + 1) * 2 - 1) * 2 + 1]) + { + S64 tmp; + tmp = heap[del_idx * 2]; + heap[del_idx * 2] = heap[((del_idx + 1) * 2 - 1) * 2]; + heap[((del_idx + 1) * 2 - 1) * 2] = tmp; + tmp = heap[del_idx * 2 + 1]; + heap[del_idx * 2 + 1] = heap[((del_idx + 1) * 2 - 1) * 2 + 1]; + heap[((del_idx + 1) * 2 - 1) * 2 + 1] = tmp; + del_idx = (del_idx + 1) * 2 - 1; + } + else if ((del_idx + 1) * 2 < heap_cnt && heap[del_idx * 2 + 1] > heap[((del_idx + 1) * 2) * 2 + 1]) + { + S64 tmp; + tmp = heap[del_idx * 2]; + heap[del_idx * 2] = heap[((del_idx + 1) * 2) * 2]; + heap[((del_idx + 1) * 2) * 2] = tmp; + tmp = heap[del_idx * 2 + 1]; + heap[del_idx * 2 + 1] = heap[((del_idx + 1) * 2) * 2 + 1]; + heap[((del_idx + 1) * 2) * 2 + 1] = tmp; + del_idx = (del_idx + 1) * 2; + } + else + break; + } + } + if (distance[item_node] < item_value) + continue; + for (i = 0; i < len; i++) + { + if (from_nodes2[i] != item_node) + continue; + if (distance[to_nodes2[i]] > distance[item_node] + values2[i]) + { + distance[to_nodes2[i]] = distance[item_node] + values2[i]; + heap[heap_cnt * 2] = to_nodes2[i]; + heap[heap_cnt * 2 + 1] = distance[to_nodes2[i]]; + { + S64 ins_idx = heap_cnt; + for (; ; ) + { + if (ins_idx > 0 && heap[ins_idx * 2 + 1] < heap[(ins_idx - 1) / 2 * 2 + 1]) + { + S64 tmp; + tmp = heap[ins_idx * 2]; + heap[ins_idx * 2] = heap[(ins_idx - 1) / 2 * 2]; + heap[(ins_idx - 1) / 2 * 2] = tmp; + tmp = heap[ins_idx * 2 + 1]; + heap[ins_idx * 2 + 1] = heap[(ins_idx - 1) / 2 * 2 + 1]; + heap[(ins_idx - 1) / 2 * 2 + 1] = tmp; + ins_idx = (ins_idx - 1) / 2; + } + else + break; + } + } + heap_cnt++; + } + } + } + FreeMem(heap); + + return result; +} + +EXPORT void* _bellmanFord(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node) +{ + THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, 0xc0000005); + THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006); + THROWDBG(node_num <= 0 || begin_node < 0 || node_num <= begin_node, 0xe9170006); + const S64* from_nodes2 = (S64*)((U8*)from_nodes + 0x10); + const S64* to_nodes2 = (S64*)((U8*)to_nodes + 0x10); + const S64* values2 = (S64*)((U8*)values + 0x10); + S64 len = *(S64*)((U8*)from_nodes + 0x08); + S64 i; +#if defined(DBG) + for (i = 0; i < len; i++) + THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i], 0xe9170006); +#endif + + U8* result = (U8*)AllocMem(0x10 + sizeof(S64) * (size_t)node_num); + ((S64*)result)[0] = DefaultRefCntFunc; + ((S64*)result)[1] = node_num; + S64* distance = (S64*)(result + 0x10); + for (i = 0; i < node_num; i++) + distance[i] = LLONG_MAX; + distance[begin_node] = 0; + + Bool found; + do + { + found = False; + for (i = 0; i < len; i++) + { + S64 from_distance = distance[from_nodes2[i]]; + if (from_distance != LLONG_MAX && distance[to_nodes2[i]] > from_distance + values2[i]) + { + distance[to_nodes2[i]] = from_distance + values2[i]; + found = True; + } + } + } while (found); + return result; +} + +EXPORT void* _floydWarshall(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values) +{ + THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, 0xc0000005); + THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006); + THROWDBG(node_num <= 0, 0xe9170006); + const S64* from_nodes2 = (S64*)((U8*)from_nodes + 0x10); + const S64* to_nodes2 = (S64*)((U8*)to_nodes + 0x10); + const S64* values2 = (S64*)((U8*)values + 0x10); + S64 len = *(S64*)((U8*)from_nodes + 0x08); + S64 i, j, k; +#if defined(DBG) + for (i = 0; i < len; i++) + THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i], 0xe9170006); +#endif + + U8* result = (U8*)AllocMem(0x10 + sizeof(void**) * (size_t)node_num); + ((S64*)result)[0] = DefaultRefCntFunc; + ((S64*)result)[1] = node_num; + void** ptr = (void**)(result + 0x10); + for (i = 0; i < node_num; i++) + { + void* item = AllocMem(0x10 + sizeof(S64) * (size_t)node_num); + ((S64*)item)[0] = 1; + ((S64*)item)[1] = node_num; + S64* ptr2 = (S64*)item + 2; + for (j = 0; j < node_num; j++) + ptr2[j] = i == j ? 0 : LLONG_MAX; + ptr[i] = item; + } + for (i = 0; i < len; i++) + ((S64*)ptr[from_nodes2[i]] + 2)[to_nodes2[i]] = values2[i]; + for (i = 0; i < node_num; i++) + { + for (j = 0; j < node_num; j++) + { + for (k = 0; k < node_num; k++) + { + S64 a = ((S64*)ptr[j] + 2)[i]; + S64 b = ((S64*)ptr[i] + 2)[k]; + if (a == LLONG_MAX || b == LLONG_MAX) + continue; + S64 value = a + b; + if (((S64*)ptr[j] + 2)[k] > value) + ((S64*)ptr[j] + 2)[k] = value; + } + } + } + + return result; +} + EXPORT SClass* _makeMat(SClass* me_, S64 row, S64 col) { THROWDBG(row <= 0 || col <= 0, 0xe9170006); diff --git a/src/lib_math/main.h b/src/lib_math/main.h index c9cc01cf..870c3f84 100644 --- a/src/lib_math/main.h +++ b/src/lib_math/main.h @@ -14,5 +14,8 @@ EXPORT double _gamma(double n); EXPORT double _fact(double n); EXPORT S64 _factInt(S64 n); EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bool reuse); +EXPORT void* _dijkstra(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node); +EXPORT void* _bellmanFord(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node); +EXPORT void* _floydWarshall(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values); EXPORT SClass* _makeMat(SClass* me_, S64 row, S64 col); EXPORT void _matDtor(SClass* me_); diff --git a/test/correct/log0021.txt b/test/correct/log0021.txt index c22f04f3..e889326d 100644 --- a/test/correct/log0021.txt +++ b/test/correct/log0021.txt @@ -8,6 +8,27 @@ Excpt: 80000003 > Not found. > 7 > 10 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 > 3 > 5 > Not found. @@ -16,6 +37,27 @@ Excpt: 80000003 > Not found. > 7 > 10 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 > 3 > 5 > Not found. @@ -24,4 +66,25 @@ Excpt: 80000003 > Not found. > 7 > 10 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 +> 0 +> 2 +> 5 +> 7 +> 11 +> 8 +> 16 end: ../../test/output/output0021.exe diff --git a/test/kn/test0021.kn b/test/kn/test0021.kn index f95de42a..a88fbb9f 100644 --- a/test/kn/test0021.kn +++ b/test/kn/test0021.kn @@ -42,5 +42,26 @@ func main() do cui@print(math@knapsack([2, 1, 3, 2], [3, 2, 4, 2], 5, false).toStr()) do cui@print(math@knapsack([3, 4, 2], [4, 5, 3], 7, true).toStr()) end block + + block + var d: []int :: math@dijkstra(7, [0, 1, 0, 2, 1, 2, 1, 3, 2, 3, 1, 4, 4, 5, 3, 5, 4, 6, 5, 6], [1, 0, 2, 0, 2, 1, 3, 1, 3, 2, 4, 1, 5, 4, 5, 3, 6, 4, 6, 5], [2, 2, 5, 5, 4, 4, 6, 6, 2, 2, 10, 10, 3, 3, 1, 1, 5, 5, 9, 9], 0) + for i(0, ^d - 1) + do cui@print(d[i].toStr()) + end for + end block + + block + var d: []int :: math@bellmanFord(7, [0, 1, 0, 2, 1, 2, 1, 3, 2, 3, 1, 4, 4, 5, 3, 5, 4, 6, 5, 6], [1, 0, 2, 0, 2, 1, 3, 1, 3, 2, 4, 1, 5, 4, 5, 3, 6, 4, 6, 5], [2, 2, 5, 5, 4, 4, 6, 6, 2, 2, 10, 10, 3, 3, 1, 1, 5, 5, 9, 9], 0) + for i(0, ^d - 1) + do cui@print(d[i].toStr()) + end for + end block + + block + var d: [][]int :: math@floydWarshall(7, [0, 1, 0, 2, 1, 2, 1, 3, 2, 3, 1, 4, 4, 5, 3, 5, 4, 6, 5, 6], [1, 0, 2, 0, 2, 1, 3, 1, 3, 2, 4, 1, 5, 4, 5, 3, 6, 4, 6, 5], [2, 2, 5, 5, 4, 4, 6, 6, 2, 2, 10, 10, 3, 3, 1, 1, 5, 5, 9, 9]) + for i(0, ^d - 1) + do cui@print(d[0][i].toStr()) + end for + end block end for end func