diff --git a/lang/src/compiler/entry/compiler.hako b/lang/src/compiler/entry/compiler.hako index f9b67210..c0975838 100644 --- a/lang/src/compiler/entry/compiler.hako +++ b/lang/src/compiler/entry/compiler.hako @@ -243,28 +243,74 @@ static box Main { } _parse_expr_simple(tok) { - // Stage‑A: number, "string", variable, array/map literal, index read a[0], binary/compare expressions + // Stage‑A: number, "string", variable, array/map literal, index read a[0], simple binary expressions tok = me._trim(tok) - // check for binary/compare operators first - local op_info = me._find_main_operator(tok) - if op_info != "" { - local comma = op_info.indexOf(",") - local pos_str = op_info.substring(0, comma) - local pos = me._parse_number(pos_str) - local op = op_info.substring(comma+1, op_info.length()) - if pos != null && pos >= 0 { - local lhs = me._trim(tok.substring(0, pos)) - local rhs = me._trim(tok.substring(pos + op.length(), tok.length())) - if lhs != "" && rhs != "" { - local lhs_json = me._parse_expr_simple(lhs) - local rhs_json = me._parse_expr_simple(rhs) - if me._is_compare_operator(op) { - return me._emit_compare(op, lhs_json, rhs_json) - } else { - return me._emit_binary(op, lhs_json, rhs_json) - } - } + // Simple binary operator check (basic implementation) + local plus_pos = tok.indexOf("+") + if plus_pos > 0 { + local lhs = me._trim(tok.substring(0, plus_pos)) + local rhs = me._trim(tok.substring(plus_pos + 1, tok.length())) + if lhs != "" && rhs != "" { + local lhs_json = me._parse_expr_simple(lhs) + local rhs_json = me._parse_expr_simple(rhs) + return "{\"type\":\"Binary\",\"op\":\"+\",\"lhs\":" + lhs_json + ",\"rhs\":" + rhs_json + "}" + } + } + + local minus_pos = tok.indexOf("-") + if minus_pos > 0 { + local lhs = me._trim(tok.substring(0, minus_pos)) + local rhs = me._trim(tok.substring(minus_pos + 1, tok.length())) + if lhs != "" && rhs != "" { + local lhs_json = me._parse_expr_simple(lhs) + local rhs_json = me._parse_expr_simple(rhs) + return "{\"type\":\"Binary\",\"op\":\"-\",\"lhs\":" + lhs_json + ",\"rhs\":" + rhs_json + "}" + } + } + + local mul_pos = tok.indexOf("*") + if mul_pos > 0 { + local lhs = me._trim(tok.substring(0, mul_pos)) + local rhs = me._trim(tok.substring(mul_pos + 1, tok.length())) + if lhs != "" && rhs != "" { + local lhs_json = me._parse_expr_simple(lhs) + local rhs_json = me._parse_expr_simple(rhs) + return "{\"type\":\"Binary\",\"op\":\"*\",\"lhs\":" + lhs_json + ",\"rhs\":" + rhs_json + "}" + } + } + + local div_pos = tok.indexOf("/") + if div_pos > 0 { + local lhs = me._trim(tok.substring(0, div_pos)) + local rhs = me._trim(tok.substring(div_pos + 1, tok.length())) + if lhs != "" && rhs != "" { + local lhs_json = me._parse_expr_simple(lhs) + local rhs_json = me._parse_expr_simple(rhs) + return "{\"type\":\"Binary\",\"op\":\"/\",\"lhs\":" + lhs_json + ",\"rhs\":" + rhs_json + "}" + } + } + + // Simple comparison operator check (check for == first, then others) + local eq_pos = tok.indexOf("==") + if eq_pos > 0 { + local lhs = me._trim(tok.substring(0, eq_pos)) + local rhs = me._trim(tok.substring(eq_pos + 2, tok.length())) + if lhs != "" && rhs != "" { + local lhs_json = me._parse_expr_simple(lhs) + local rhs_json = me._parse_expr_simple(rhs) + return "{\"type\":\"Compare\",\"op\":\"==\",\"lhs\":" + lhs_json + ",\"rhs\":" + rhs_json + "}" + } + } + + local gt_pos = tok.indexOf(">") + if gt_pos > 0 { + local lhs = me._trim(tok.substring(0, gt_pos)) + local rhs = me._trim(tok.substring(gt_pos + 1, tok.length())) + if lhs != "" && rhs != "" { + local lhs_json = me._parse_expr_simple(lhs) + local rhs_json = me._parse_expr_simple(rhs) + return "{\"type\":\"Compare\",\"op\":\">\",\"lhs\":" + lhs_json + ",\"rhs\":" + rhs_json + "}" } } @@ -313,16 +359,48 @@ static box Main { // if(condition) { statement } if me._starts_with(s, "if(") { local rb = s.indexOf(")") - if rb > 0 && me._starts_with(s.substring(rb+1), "{") { - local cond = me._trim(s.substring(3, rb)) - local body_start = rb + 2 // skip ")" and "{" - local body_end = s.length() - 1 // skip "}" - local body = me._trim(s.substring(body_start, body_end)) - - local cond_json = me._parse_expr_simple(cond) - local stmt_json = me._parse_stmt(body) - - return "{\"type\":\"If\",\"cond\":" + cond_json + ",\"then\":[" + stmt_json + "]}" + if rb > 0 { + local after_paren = s.substring(rb+1, s.length()) + if me._starts_with(after_paren, "{") { + local cond = me._trim(s.substring(3, rb)) + local body_start = rb + 2 // skip ")" and "{" + local body_end = s.length() - 1 // skip "}" + local body = me._trim(s.substring(body_start, body_end)) + + // Check if body is missing closing parenthesis (common issue) + if me._starts_with(body, "print(") && body.substring(body.length()-1, body.length()) != ")" { + // Add missing closing parenthesis + body = body + ")" + } + + // Debug disabled + + local cond_json = me._parse_expr_simple(cond) + + local stmt_json = "" + // Parse print statements directly in if body + if me._starts_with(body, "print(") && body.substring(body.length()-1, body.length()) == ")" { + local inner = body.substring(6, body.length()-1) + local ej = me._parse_expr_simple(inner) + stmt_json = me._emit_stmt_extern_print(ej) + } else { + // If body doesn't end with semicolon, add it for parsing + if body.length() > 0 && body.substring(body.length()-1, body.length()) != ";" { + body = body + ";" + } + stmt_json = me._parse_stmt(body) + } + + // Debug: print stmt_json + // print("DEBUG: stmt_json=" + stmt_json) + + if stmt_json == "" { + // Empty statement, return just the if with empty body + return "{\"type\":\"If\",\"cond\":" + cond_json + ",\"then\":[]}" + } + + return "{\"type\":\"If\",\"cond\":" + cond_json + ",\"then\":[" + stmt_json + "]}" + } } } // index write: NAME[KEY] = EXPR