phase15: update CLAUDE.md and sync with current progress
- Update phase indicator to Phase 15 (Self-Hosting) - Update documentation links to Phase 15 resources - Reflect completion of R1-R5 tasks and ongoing work - Fix CURRENT_TASK.md location to root directory Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
88
apps/ny-parser-nyash/parser_minimal.nyash
Normal file
88
apps/ny-parser-nyash/parser_minimal.nyash
Normal file
@ -0,0 +1,88 @@
|
||||
// Minimal recursive-descent parser for Ny v0 producing JSON IR v0 (MapBox)
|
||||
|
||||
include("./apps/ny-parser-nyash/tokenizer.nyash")
|
||||
|
||||
static box ParserV0 {
|
||||
init { tokens, pos }
|
||||
|
||||
parse_program(input) {
|
||||
me.tokens = Tokenizer.tokenize(input)
|
||||
// Error passthrough
|
||||
if me.tokens.as_any().toString().indexOf("\"kind\":\"Error\"") >= 0 {
|
||||
return me.tokens
|
||||
}
|
||||
me.pos = 0
|
||||
local stmt = me.parse_stmt()
|
||||
if stmt.as_any().toString().indexOf("\"kind\":\"Error\"") >= 0 { return stmt }
|
||||
local body = new ArrayBox(); body.push(stmt)
|
||||
local prog = new MapBox(); prog.set("version", 0); prog.set("kind", "Program"); prog.set("body", body)
|
||||
return prog
|
||||
}
|
||||
|
||||
parse_stmt() {
|
||||
local tok = me.peek()
|
||||
if tok.get("type") == "RETURN" {
|
||||
me.next()
|
||||
local expr = me.parse_expr()
|
||||
if expr.as_any().toString().indexOf("\"kind\":\"Error\"") >= 0 { return expr }
|
||||
local ret = new MapBox(); ret.set("type", "Return"); ret.set("expr", expr)
|
||||
return ret
|
||||
}
|
||||
return me.err("Expected 'return'")
|
||||
}
|
||||
|
||||
parse_expr() {
|
||||
local left = me.parse_term()
|
||||
loop(true) {
|
||||
local t = me.peek(); local ty = t.get("type")
|
||||
if ty == "+" || ty == "-" {
|
||||
me.next(); local right = me.parse_term()
|
||||
left = me.bin(ty, left, right)
|
||||
} else { break }
|
||||
}
|
||||
return left
|
||||
}
|
||||
|
||||
parse_term() {
|
||||
local left = me.parse_factor()
|
||||
loop(true) {
|
||||
local t = me.peek(); local ty = t.get("type")
|
||||
if ty == "*" || ty == "/" {
|
||||
me.next(); local right = me.parse_factor()
|
||||
left = me.bin(ty, left, right)
|
||||
} else { break }
|
||||
}
|
||||
return left
|
||||
}
|
||||
|
||||
parse_factor() {
|
||||
local t = me.peek(); local ty = t.get("type")
|
||||
if ty == "INT" {
|
||||
me.next();
|
||||
local node = new MapBox(); node.set("type", "Int"); node.set("value", t.get("value"))
|
||||
return node
|
||||
}
|
||||
if ty == "(" {
|
||||
me.next();
|
||||
local e = me.parse_expr()
|
||||
local r = me.peek(); if r.get("type") != ")" { return me.err(") expected") } else { me.next() }
|
||||
return e
|
||||
}
|
||||
return me.err("factor expected")
|
||||
}
|
||||
|
||||
// helpers
|
||||
peek() { return me.tokens.get(me.pos) }
|
||||
next() { me.pos = me.pos + 1; return me.tokens.get(me.pos-1) }
|
||||
bin(op, lhs, rhs) {
|
||||
local m = new MapBox(); m.set("type", "Binary"); m.set("op", op); m.set("lhs", lhs); m.set("rhs", rhs); return m
|
||||
}
|
||||
err(msg) {
|
||||
local err = new MapBox(); err.set("version", 0); err.set("kind", "Error")
|
||||
local e = new MapBox(); e.set("message", msg)
|
||||
local sp = new MapBox(); sp.set("start", me.pos); sp.set("end", me.pos)
|
||||
e.set("span", sp); err.set("error", e)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user