From 036fd37a1290dbcfb09ba6a7a7d671bb91f1eaa0 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Wed, 16 Jul 2025 02:40:43 +0000 Subject: [PATCH] compile most things --- soh/compile_logic.py | 140 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/soh/compile_logic.py b/soh/compile_logic.py index 444a74893..c004decc0 100755 --- a/soh/compile_logic.py +++ b/soh/compile_logic.py @@ -52,8 +52,146 @@ for line in open(argv[1]): active_rr.events.append((thing, code)) buf = "" +def parse(code): + if code[0] == "(" and code[-1] == ")": + code = code[1:-1] + stack = [] + ast = [] + balance = 0 + lastidx = 0 + for idx, ch in enumerate(code): + if ch.isspace(): + if idx > lastidx: + ast.append(code[lastidx:idx]) + lastidx = idx+1 + elif ch == "(": + stack.append(ast) + ast = [] + lastidx = idx+1 + elif ch == ")": + if idx > lastidx: + ast.append(code[lastidx:idx]) + subast = ast + ast = stack.pop() + ast.append(subast) + lastidx = idx+1 + if len(code) > lastidx: + ast.append(code[lastidx:]) + return ast + +def to_cpp(ast): + result = [] + output = result.append + if ast: + if isinstance(ast, str): + f = ast + ast = [f] + else: + f = ast[0] + if f in LOGIC: + output(f"logic->{f}") + elif f in logicFUNC: + output(f"logic->{f}(") + output(", ".join(map(to_cpp, ast[1:]))) + output(")") + elif f in ctxFUNC: + output(f"ctx->{f}(") + output(", ".join(map(to_cpp, ast[1:]))) + output(")") + elif f in binOP: + output("(") + output(binOP[f].join(map(to_cpp, ast[1:]))) + output(")") + elif f == "not": + output("!") + output(to_cpp(ast[1])) + elif f == "if": + output("(") + output(to_cpp(ast[1])) + output(" ? ") + output(to_cpp(ast[2])) + output(" : ") + output(to_cpp(ast[3])) + output(")") + else: + if not (f.isupper() or f.isdigit() or f in ("true", "false")): + print("cannot convert", f, ast) + output(f) + return "".join(result) + +binOP = { "==": " == ", "and": " && ", "or": " || ", ">=": " >= ", "!=": " != ", ">": " > ", "<": " < ", "add": " + " } + +LOGIC = set(( + "IsChild", + "IsAdult", + "AtDay", + "AtNight", + "LoweredWaterInBotw", + "TriforcePiecesCollected", +)) + +logicFUNC = set(( + "HasAccessTo", + "BlueFire", + "CanBreakMudWalls", + "HasItem", + "HasBossSoul", + "HasFireSource", + "HasFireSourceWithTorch", + "CanUse", + "CanPassEnemy", + "CanKillEnemy", + "CanGetEnemyDrop", + "CanGetDekuBabaSticks", + "CanGetDekuBabaNuts", + "CanBreakPots", + "CanBorrowMasks", + "CanShield", + "CanReflectNuts", + "CanStunDeku", + "CanSpawnSoilSkull", + "CanGetNightTimeGS", + "CanHitSwitch", + "CanHitEyeTargets", + "CanDetonateUprightBombFlower", + "CanDetonateBombFlowers", + "CanUseProjectile", + "CanBreakLowerBeehives", + "CanBreakUpperBeehives", + "CallGossipFairy", + "CallGossipFairyExceptSuns", + "HasExplosives", + "CanCutShrubs", + "CanBreakCrates", + "CanBreakSmallCrates", + "CanPlantBean", + "StoneCount", + "CanBuildRainbowBridge", + "TradeQuestStep", + "GetGSCount", + "BlastOrSmash", + "HookshotOrBoomerang", + "TakeDamage", + "CanAttack", + "CanUseSword", + "CanJumpslash", + "CanJumpslashExceptHammer", + "HasBottle", + "SmallKeys", + "OcarinaButtons", + "Hearts", + "EffectiveHealth", + "FireTimer", + "WaterTimer", +)) + +ctxFUNC = set(( + "GetTrickOption", + "GetOption" +)) + def gen(code): - return code + return to_cpp(parse(code)) result = [] output = result.append