ref: da5bfc6d15a50130afdcd37ed9af737a81724506
dir: /mparse/parse.myr/
use std
use "ast.use"
use "stab.use"
use "types.use"
use "tokdefs.use"
use "tok.use"
use "util.use"
pkg parse =
const tsfile : (ts : tokstream# -> file#)
;;
const tsfile = {ts
var f
f = std.mk([
.uses = [][:],
.libs = [][:],
.extlibs = [][:],
.dcls = [][:],
.extinit = [][:],
.init = `std.None,
.globls = mkstab(),
.builtin = mkstab(),
.ns = std.mkht(std.strhash, std.streq),
])
f.globls.super = `std.Some f.builtin
optendlns(ts)
while true
match tokpeek(ts)
| (loc, `Teof):
break
| (loc, `Tuse):
usestmt(ts, f)
| (loc, `Tpkg):
pkgdef(ts, f)
| (loc, `Ttrait):
traitdef(ts, f)
| (loc, `Ttype):
tydef(ts, f)
| (loc, tok):
if !decl(ts, ts)
err(loc, "invalid top level item near {}", tok)
;;
;;
endlns(ts)
;;
-> f
}
const usestmt = {ts, f
match toknext(ts)
| (loc, `Tuse): /* ok */
| (loc, t): err(loc, "unexpected token in use {}\n", t)
;;
match toknext(ts)
| (loc, `Tstrlit str): f.uses = std.slpush(f.uses, `Ulocal str)
| (loc, `Tident id): f.uses = std.slpush(f.uses, `Ulib id)
| (loc, t): err(loc, "unexpected {} after use\n", t)
;;
}
const pkgdef = {ts, f
match toknext(ts)
| (loc, `Tpkg): /* ok */
| (loc, t): err(loc, "unexpected token in pkg {}\n", t)
;;
match toknext(ts)
| (loc, `Tident id): setpkg(f, f.globls, id)
| (loc, `Tgap): /* pkg _ */
| (loc, t): err(loc, "invalid package name {}\n", t)
;;
match toknext(ts)
| (loc, `Tasn): /* ok */
| (loc, t): err(loc, "expected '=' after pkg name, got {}\n", t)
;;
pkgbody(ts, f)
expectendblk(ts, f)
}
const pkgbody = {ts, f
optendlns(ts)
}
const traitdef = {ts, f
}
const tydef = {ts, f
}
const decl = {ts, f
-> false
}
const endlns = {ts
match tokpeek(ts)
| (loc, `Tendln): optendlns(ts)
| (loc, t): err(loc, "expected \\n, got {}\n", t)
;;
}
const optendlns = {ts
while true
match tokpeek(ts)
| (loc, `Tendln): toknext(ts)
| _: break
;;
;;
}
const expectendblk = {ts, f
match toknext(ts)
| (loc, `Tendblk): /* ok */
| (loc, t): err(loc, "expected ;; after block, got {}\n", t)
;;
}