ref: ac297020506255ca01cde01c14145f3203d1a155
parent: 8bc429fb93070938b8bc5d459da4f2664c00abae
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Jan 7 20:19:36 EST 2016
Start of parsing files.
--- /dev/null
+++ b/mparse/ast.myr
@@ -1,0 +1,10 @@
+use std
+
+use "types.use"
+use "tokdefs.use"
+use "tok.use"
+use "util.use"
+
+pkg parse =
+;;
+
--- a/mparse/bld.proj
+++ b/mparse/bld.proj
@@ -1,7 +1,11 @@
bin tok =
+ ast.myr
+ dump.myr
main.myr
- types.myr
+ parse.myr
+ stab.myr
tok.myr
tokdefs.myr
+ types.myr
util.myr
;;
--- /dev/null
+++ b/mparse/dump.myr
@@ -1,0 +1,185 @@
+use std
+
+use "types.use"
+use "util.use"
+
+pkg parse =
+;;
+
+const __init__ = {
+ var f : file
+ var d : dcl
+ var st : stab
+ var e : expr
+
+ std.fmtinstall(std.typeof(&f), fmtfile, [][:])
+ std.fmtinstall(std.typeof(&d), fmtdcl, [][:])
+ /*std.fmtinstall(std.typeof(&n), fmtnode, [][:])*/
+ std.fmtinstall(std.typeof(&e), fmtexpr, [][:])
+ std.fmtinstall(std.typeof(&st), fmtstab, [][:])
+}
+
+/*
+const fmtnode = {sb, ap, opts
+ var f : node#
+ f = std.vanext(ap)
+ nodedump(sb, f, 0)
+}
+*/
+
+generic fmtfile = {sb, ap, opts
+ var f : file#
+ f = std.vanext(ap)
+ filedump(sb, f, 0)
+}
+
+const fmtdcl = {sb, ap, opts
+ var f : dcl#
+ f = std.vanext(ap)
+ dcldump(sb, f, 0)
+}
+
+const fmtstab = {sb, ap, opts
+ var f : stab#
+ f = std.vanext(ap)
+ stabdump(sb, f, 0)
+}
+
+const fmtexpr = {sb, ap, opts
+ var f : expr#
+ f = std.vanext(ap)
+ exprdump(sb, f)
+}
+
+
+const filedump = {sb, f, ind
+ ifmt(sb, ind, "file: {}\n", f.path)
+ for u in f.uses
+ match u
+ | `Ulocal l: ifmt(sb, ind + 1, "local-use:\t{}\n", l)
+ | `Ulib l: ifmt(sb, ind + 1, "lib-use:\t{}\n", l)
+ ;;
+ ;;
+ ifmt(sb, ind, "libs: {}\n", f.extlibs)
+ ifmt(sb, ind, "extlibs: {}\n", f.extlibs)
+
+ for i in f.extinit
+ dcldump(sb, i, ind + 1)
+ ;;
+
+ match f.init
+ | `std.Some d: dcldump(sb, d, ind + 1)
+ | `std.None:
+ ;;
+
+ stabdump(sb, f.builtin, ind + 1)
+ stabdump(sb, f.globls, ind + 1)
+
+ for s in f.dcls
+ dcldump(sb, s, ind + 1)
+ ;;
+}
+
+const dcldump = {sb, dcl, ind
+ ifmt(sb, ind, "{}: {} {}: {}\t", dcl.id, dcl.vis, dcl.name, dcl.ty)
+ ifmt(sb, ind + 2, "globl:{}, const:{}, noret:{}, init:{}, exportinit:{}\n", \
+ dcl.isglobl, dcl.isconst, dcl.isnoret, dcl.isinit, dcl.isexportinit)
+ ifmt(sb, ind + 2, "extern:{}, import:{}, hidden:{}, pkglocal:{}, generic:{}\n", \
+ dcl.isextern, dcl.isimport, dcl.ishidden, dcl.ispkglocal, dcl.isgeneric)
+ ifmt(sb, ind + 1, "{}", dcl.init)
+}
+
+const exprdump = {sb, e
+ match e#
+ | [.e = `Oadd (a, b)]: std.sbfmt(sb, "{} + {}", a, b)
+ | [.e = `Osub (a, b)]: std.sbfmt(sb, "{} - {}", a, b)
+ | [.e = `Omul (a, b)]: std.sbfmt(sb, "{} * {}", a, b)
+ | [.e = `Odiv (a, b)]: std.sbfmt(sb, "{} / {}", a, b)
+ | [.e = `Omod (a, b)]: std.sbfmt(sb, "{} % {}", a, b)
+ | [.e = `Oneg exp]: std.sbfmt(sb, "-{}", exp)
+ | [.e = `Obor (a, b)]: std.sbfmt(sb, "{} | {}", a, b)
+ | [.e = `Oband (a, b)]: std.sbfmt(sb, "{} & {}", a, b)
+ | [.e = `Obxor (a, b)]: std.sbfmt(sb, "{} ^ {}", a, b)
+ | [.e = `Obsl (a, b)]: std.sbfmt(sb, "{} << {}", a, b)
+ | [.e = `Obsr (a, b)]: std.sbfmt(sb, "{} >> {}", a, b)
+ | [.e = `Obnot exp]: std.sbfmt(sb, "~{}", exp)
+ | [.e = `Opreinc exp]: std.sbfmt(sb, "++{}", exp)
+ | [.e = `Opostinc exp]: std.sbfmt(sb, "{}++", exp)
+ | [.e = `Opredec exp]: std.sbfmt(sb, "++{}", exp)
+ | [.e = `Opostdec exp]: std.sbfmt(sb, "{}--", exp)
+ | [.e = `Oaddr exp]: std.sbfmt(sb, "&{}", exp)
+ | [.e = `Oderef exp]: std.sbfmt(sb, "{}#", exp)
+ | [.e = `Olor (a, b)]: std.sbfmt(sb, "{} || {}", a, b)
+ | [.e = `Oland (a, b)]: std.sbfmt(sb, "{} && {}", a, b)
+ | [.e = `Olnot exp]: std.sbfmt(sb, "!{}", exp)
+ | [.e = `Oeq (a, b)]: std.sbfmt(sb, "{} == {}", a, b)
+ | [.e = `One (a, b)]: std.sbfmt(sb, "{} != {}", a, b)
+ | [.e = `Ogt (a, b)]: std.sbfmt(sb, "{} > {}", a, b)
+ | [.e = `Oge (a, b)]: std.sbfmt(sb, "{} >= {}", a, b)
+ | [.e = `Olt (a, b)]: std.sbfmt(sb, "{} < {}", a, b)
+ | [.e = `Ole (a, b)]: std.sbfmt(sb, "{} <= {}", a, b)
+ | [.e = `Oasn (a, b)]: std.sbfmt(sb, "{} = {}", a, b)
+ | [.e = `Oaddeq (a, b)]: std.sbfmt(sb, "{} += {}", a, b)
+ | [.e = `Osubeq (a, b)]: std.sbfmt(sb, "{} -= {}", a, b)
+ | [.e = `Omuleq (a, b)]: std.sbfmt(sb, "{} *= {}", a, b)
+ | [.e = `Odiveq (a, b)]: std.sbfmt(sb, "{} /= {}", a, b)
+ | [.e = `Omodeq (a, b)]: std.sbfmt(sb, "{} %= {}", a, b)
+ | [.e = `Oboreq (a, b)]: std.sbfmt(sb, "{} |= {}", a, b)
+ | [.e = `Obandeq (a, b)]: std.sbfmt(sb, "{} &= {}", a, b)
+ | [.e = `Obxoreq (a, b)]: std.sbfmt(sb, "{} ^= {}", a, b)
+ | [.e = `Obsleq (a, b)]: std.sbfmt(sb, "{} <<= {}", a, b)
+ | [.e = `Obsreq (a, b)]: std.sbfmt(sb, "{} >>= {}", a, b)
+ | [.e = `Oidx (a, b)]: std.sbfmt(sb, "{}[{}]", a, b)
+ | [.e = `Oslice (a, b, c)]: std.sbfmt(sb, "{}[{} : {}]", a, b, c)
+ | [.e = `Omemb (a, memb)]: std.sbfmt(sb, "{}.{}", a, memb)
+ | [.e = `Osize ty]: std.sbfmt(sb, "sizeof({})", ty)
+ | [.e = `Ocast exp]: std.sbfmt(sb, "{} castto({})", exp)
+ | [.e = `Oret exp]: std.sbfmt(sb, "-> {}", exp)
+ | [.e = `Ojmp name]: std.sbfmt(sb, "goto {}", name)
+ | [.e = `Obreak]: std.sbfmt(sb, "break")
+ | [.e = `Ocontinue]: std.sbfmt(sb, "continue")
+ | [.e = `Ovar name]: std.sbfmt(sb, "{}", name)
+ | [.e = `Ogap]: std.sbfmt(sb, "_")
+ | [.e = `Olit lit]: std.sbfmt(sb, "{}", lit)
+ | [.e = `Ocall (f, args)]: std.sbfmt(sb, "{}({})", f, args)
+ | [.e = `Oucon (t, `std.Some v)]:
+ std.sbfmt(sb, "{} {}", t, v)
+ | [.e = `Oucon (t, `std.None)]:
+ std.sbfmt(sb, "{}", t)
+ | [.e = `Otup al]:
+ std.sbfmt(sb, "{}", al)
+ | [.e = `Ostruct ml]:
+ std.sbfmt(sb, "{}", ml)
+ | [.e = `Oarr il]:
+ std.sbfmt(sb, "{}", il)
+ | [.e = `Oidxlen]:
+ std.sbfmt(sb, "$")
+ ;;
+}
+
+const stabdump = {sb, st, ind
+ var keys
+
+ if st.name.len != 0
+ ifmt(sb, ind, "ns: {}", st.name)
+ ;;
+ keys = std.htkeys(st.syms)
+ for k in keys
+ match std.get(std.htget(st.syms, k))
+ | `Dcl d: ifmt(sb, ind, "{} : {}\n", k, d.ty)
+ | `Ucon uc: ifmt(sb, ind, "{} : {}\n", k, uc.ety)
+ ;;
+ ;;
+ std.slfree(keys)
+
+ keys = std.htkeys(st.types)
+ for k in keys
+ match std.get(std.htget(st.types, k))
+ | `Tyfwd: ifmt(sb, ind, "type {} [PROTO]", k)
+ | `Trfwd: ifmt(sb, ind, "trait {} [PROTO]", k)
+ | `Tydef d: ifmt(sb, ind, "type {} = {}\n", k, d)
+ | `Trdef tr: ifmt(sb, ind, "trait {} = ...\n", k)
+ ;;
+ ;;
+ std.slfree(keys)
+}
--- a/mparse/main.myr
+++ b/mparse/main.myr
@@ -1,15 +1,11 @@
use std
use "tok.use"
+use "parse.use"
const main = {
var ts
ts = parse.tokinitf(0)
- while true
- match parse.toknext(ts)
- | `parse.Teof: break
- | tok: std.put("{}\n", tok)
- ;;
- ;;
+ parse.tsfile(ts)
}
--- /dev/null
+++ b/mparse/parse.myr
@@ -1,0 +1,92 @@
+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 = [][:],
+ .stmts = [][:],
+ .extinit = [][:],
+ .init = `std.None,
+ .globls = mkstab(),
+ .builtin = mkstab(),
+ ])
+ f.globls.super = `std.Some f.builtin
+ while true
+ match tokpeek(ts)
+ | (loc, `Teof):
+ break
+ | (loc, `Tendln):
+ continue
+
+ | (loc, `Tuse):
+ usestmt(ts, f)
+ | (loc, `Tpkg):
+ pkgdef(ts, f)
+ | (loc, `Ttrait):
+ traitdef(ts, f)
+ | (loc, `Ttype):
+ tydef(ts, f)
+ | _:
+ decl(ts, ts)
+ ;;
+ ;;
+ -> f
+}
+
+const usestmt = {ts, f
+}
+
+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
+}
+
+const traitdef = {ts, f
+}
+
+const tydef = {ts, f
+}
+
+const decl = {ts, f
+}
+
+const expectendblk = {ts, f
+ match toknext(ts)
+ | (loc, `Tendblk): /* ok */
+ | (loc, t): err(loc, "expected ;; after block, got {}\n", t)
+ ;;
+}
--- /dev/null
+++ b/mparse/stab.myr
@@ -1,0 +1,39 @@
+use std
+
+use "types.use"
+use "tokdefs.use"
+use "tok.use"
+use "util.use"
+
+pkg parse =
+ const setpkg : (f : file#, st : stab#, name : byte[:]-> void)
+ const mkstab : (-> stab#)
+;;
+
+const mkstab = {
+ -> std.mk([
+ .super = `std.None,
+ .name = "",
+ .isfunc = false,
+ .syms = std.mkht(stnamehash, stnameeq),
+ .impls = std.mkht(stnamehash, stnameeq),
+ .env = std.mkht(stnamehash, stnameeq),
+ ])
+}
+
+const setpkg = {f, st, name
+ if st.name.len != 0
+ std.fatal("package name already set for pkg {}\n", st.name)
+ ;;
+ st.name = name
+ std.htput(f.ns, name, st)
+}
+
+const stnamehash = {n : name#
+ -> std.strhash(n.name)
+}
+
+const stnameeq = {a, b
+ -> std.streq(a.name, b.name)
+}
+
--- a/mparse/tok.myr
+++ b/mparse/tok.myr
@@ -6,7 +6,7 @@
pkg parse =
type tokstream = struct
- next : std.option(tok)
+ next : std.option((srcloc, tok))
rest : byte[:]
data : byte[:]
loc : srcloc
@@ -16,8 +16,8 @@
const tokinitf : (path : std.fd -> tokstream#)
const tokclose : (ts : tokstream# -> void)
- const toknext : (ts : tokstream# -> tok)
- const tokpeek : (ts : tokstream# -> tok)
+ const toknext : (ts : tokstream# -> (srcloc, tok))
+ const tokpeek : (ts : tokstream# -> (srcloc, tok))
;;
const Eof = std.Badchar
@@ -46,11 +46,9 @@
match ts.next
| `std.Some tok:
ts.next = `std.None
- std.put("tok: {}\n", tok)
-> tok
| `std.None:
t = tokread(ts)
- std.put("t: {}\n", t)
-> t
;;
}
@@ -68,30 +66,31 @@
;;
}
-const tokread : (ts : tokstream# -> tok) = {ts
- var c
+const tokread = {ts
+ var c, loc
skipspace(ts)
+ loc = ts.loc
c = peekc(ts)
if ts.rest.len == 0
- -> `Teof
+ -> (loc, `Teof)
elif c == '\n'
takec(ts)
ts.loc.line++
ts.loc.col = 1
- -> `Tendln
+ -> (loc, `Tendln)
elif c == '\''
- -> chrlit(ts)
+ -> (loc, chrlit(ts))
elif c == '"'
- -> strlit(ts)
+ -> (loc, strlit(ts))
elif c == '@'
- -> typaram(ts)
- elif isident(c)
- -> kwident(ts)
+ -> (loc, typaram(ts))
elif std.isdigit(c)
- -> numlit(ts)
+ -> (loc, numlit(ts))
+ elif isident(c)
+ -> (loc, kwident(ts))
else
- -> oper(ts)
+ -> (loc, oper(ts))
;;
}
@@ -267,12 +266,13 @@
const numlit = {ts
var t
+ std.put("parsing number: {}\n", ts.rest[:10])
if matchc(ts, '0')
if matchc(ts, 'x')
t = number(ts, 16)
elif matchc(ts, 'b')
t = number(ts, 2)
- elif matchc('o')
+ elif matchc(ts, 'o')
t = number(ts, 8)
else
t = number(ts, 10)
@@ -283,6 +283,7 @@
-> t
}
+
/*
only deals with the body of the number. if we reach
this code, then it's guaranteed that we already have
@@ -289,7 +290,54 @@
a numerical value.
*/
const number = {ts, base
+ var buf, nbuf
+ var isfloat, issigned
+ var v, bits
+ buf = ts.rest
+ nbuf = 0
+ isfloat = false
+ for var c = peekc(ts); std.isxdigit(c) || c == '.' || c == '_'; c = peekc(ts)
+ takec(ts)
+ if c == '_'
+ continue
+ elif c == '.'
+ isfloat = true
+ else
+ v = std.charval(c, base)
+ if v < 0
+ err(ts.loc, "digit {} out of range of base {}\n", c, base)
+ ;;
+ ;;
+ nbuf++
+ ;;
+
+ if isfloat
+ if base != 10
+ err(ts.loc, "floats must be in base 10\n")
+ ;;
+ std.fatal("unable to parse floats: fuck me\n")
+ /*
+ -> `Tfltlit std.flt64parse(buf[:n])
+ */
+ else
+ issigned = true
+ if peekc(ts) == 'u'
+ takec(ts)
+ issigned = false
+ ;;
+
+ match peekc(ts)
+ | 'l': bits = 64
+ | 'i': bits = 32
+ | 's': bits = 16
+ | 'b': bits = 8
+ | _: bits = 0
+ ;;
+ v = std.get(std.intparsebase(buf[:nbuf], base))
+ /* guaranteed to be ok */
+ -> `Tintlit (v, bits, issigned)
+ ;;
}
const kwident = {ts
@@ -332,7 +380,6 @@
var t, chr
chr = takec(ts)
- std.put("c = '{}'\n", chr)
t = `Tobrace
match chr
| '{': t = `Tobrace
--- a/mparse/tokdefs.myr
+++ b/mparse/tokdefs.myr
@@ -66,7 +66,7 @@
`Tbreak /* break */
`Tcontinue /* continue */
- `Tintlit int64
+ `Tintlit (int64, int, bool) /* val, sz, sign */
`Tstrlit byte[:]
`Tfltlit flt64
`Tchrlit char
--- a/mparse/types.myr
+++ b/mparse/types.myr
@@ -1,3 +1,5 @@
+use std
+
pkg parse =
type srcloc = struct
file : byte[:]
@@ -9,5 +11,280 @@
`Attrpkglocal
`Attrextern
`Attrnoret
+ ;;
+
+ type file = struct
+ path : byte[:]
+ uses : usefile[:]
+ libs : byte[:][:]
+ extlibs : byte[:][:]
+ extinit : dcl#[:]
+ init : std.option(dcl#)
+ builtin : stab#
+ globls : stab#
+ ns : std.htab(byte[:], node#)#
+ dcls : dcl#[:]
+ ;;
+
+ type node = union
+ `Nexpr expr
+ `Nlit lit
+ `Nloop loopstmt
+ `Niter iterstmt
+ `Nif ifstmt
+ `Nmatch matchstmt
+ `Ncase matchcase
+ `Ndcl dcl#
+ `Nfunc func
+ `Ntrait traitdef
+ `Nimpl impldef
+ ;;
+
+ type tydef = struct
+ ty : ty
+ id : int32
+ loc : srcloc
+ fixed : bool
+ found : bool
+ traits : std.bitset#
+ ;;
+
+ type ty = union
+ `Tyvoid
+ `Tybool
+ /* integers */
+ `Tyint8
+ `Tyint16
+ `Tyint32
+ `Tyint
+ /* unsigned integers */
+ `Tychar
+ `Tybyte
+ `Tyint64
+ `Tyuint8
+ `Tyuint16
+ `Tyuint32
+ `Tyuint
+ `Tyuint64
+ /*floats */
+ `Tyflt32
+ `Tyflt64
+ /* a bit odd.. */
+ `Tyvalist
+ /* compound types */
+ `Tyslice tydef#
+ `Typtr tydef#
+ `Tyarray (tydef#, node#)
+ `Tystruct (dcl#[:])
+ `Tyunion (ucon#[:])
+ /* user defined types */
+ `Tygeneric (tydef#[:], tydef#)
+ `Tyname (tydef#[:], tydef#)
+ `Typaram byte[:]
+ `Tyvar int64
+ ;;
+
+ type ucon = struct
+ loc : srcloc
+ name : name#
+ uty : tydef#
+ ety : std.option(tydef#)
+ ;;
+
+ type impldef = struct
+ vis : vis
+ tr : name#
+ ty : tydef#
+ aux : tydef#[:]
+ dcls : dcl#[:]
+ isimport : bool
+ ;;
+
+ type expr = struct
+ ty : tydef#
+ loc : srcloc
+ e : union
+ `Oadd (node#, node#)
+ `Osub (node#, node#)
+ `Omul (node#, node#)
+ `Odiv (node#, node#)
+ `Omod (node#, node#)
+ `Oneg node#
+ `Obor (node#, node#)
+ `Oband (node#, node#)
+ `Obxor (node#, node#)
+ `Obsl (node#, node#)
+ `Obsr (node#, node#)
+ `Obnot node#
+ `Opreinc node#
+ `Opostinc node#
+ `Opredec node#
+ `Opostdec node#
+ `Oaddr node#
+ `Oderef node#
+ `Olor (node#, node#)
+ `Oland (node#, node#)
+ `Olnot node#
+ `Oeq (node#, node#)
+ `One (node#, node#)
+ `Ogt (node#, node#)
+ `Oge (node#, node#)
+ `Olt (node#, node#)
+ `Ole (node#, node#)
+ `Oasn (node#, node#)
+ `Oaddeq (node#, node#)
+ `Osubeq (node#, node#)
+ `Omuleq (node#, node#)
+ `Odiveq (node#, node#)
+ `Omodeq (node#, node#)
+ `Oboreq (node#, node#)
+ `Obandeq (node#, node#)
+ `Obxoreq (node#, node#)
+ `Obsleq (node#, node#)
+ `Obsreq (node#, node#)
+ `Oidx (node#, node#)
+ `Oslice (node#, node#, node#)
+ `Omemb (node#, byte[:])
+ `Osize ty#
+ `Ocall (node#, node#[:])
+ `Ocast node#
+ `Oret node#
+ `Ojmp name#
+ `Obreak
+ `Ocontinue
+ `Ovar name#
+ `Ogap
+ `Olit lit
+ `Oucon (name#, std.option(node#))
+ `Otup node#[:]
+ `Ostruct (name#, node#)[:]
+ `Oarr (node#, node#)[:]
+ `Oidxlen
+ ;;
+ ;;
+
+ type dcl = struct
+ id : int32
+ name : name
+ vis : vis
+
+ ty : tydef#
+ init : expr#
+ tr : traitdef#
+ impls : std.htab(tydef#, dcl#)
+
+ isglobl : bool
+ isconst : bool
+ isnoret : bool
+ isinit : bool
+ isexportinit : bool
+ isextern : bool
+ isimport : bool
+ ishidden : bool
+ ispkglocal : bool
+ isgeneric : bool
+ ;;
+
+ type loopstmt = struct
+ init : expr#
+ cond : expr#
+ step : expr#
+ body : block#
+ scope : stab#
+ ;;
+
+ type iterstmt = struct
+ elt : expr#
+ seq : expr#
+ body : block#
+ ;;
+
+ type ifstmt = struct
+ cond : expr#
+ iftrue : block#
+ iffalse : block#
+ ;;
+
+ type block = struct
+ stab : stab#
+ stmts : node#[:]
+ ;;
+
+ type matchstmt = struct
+ val : expr#
+ matches : matchcase#[:]
+ ;;
+
+ type matchcase = struct
+ expr : node#
+ blk : block#
+ ;;
+
+ type lit = union
+ `Lint uint64
+ `Lflt flt64
+ `Lchr char
+ `Lstr byte[:]
+ `Llbl byte[:]
+ `Lbool bool
+ `Lvoid
+ ;;
+
+ type traitdef = struct
+ id : int32
+ loc : srcloc
+ vis : vis
+ name : name
+ param : tydef#
+ aux : tydef#[:]
+ memb : dcl#[:]
+ funcs : dcl#[:]
+ ;;
+
+ type usefile = union
+ `Ulocal byte[:]
+ `Ulib byte[:]
+ ;;
+
+ type func = struct
+ stab : stab#
+ ty : tydef#
+ args : dcl#[:]
+ body : block#
+ ;;
+
+ type stab = struct
+ super : std.option(stab#)
+ name : byte[:]
+ isfunc : bool
+
+ syms : std.htab(name, sym)#
+ types : std.htab(name, tysym)#
+ impls : std.htab(name, node#)#
+ env : std.htab(name, node#)#
+ ;;
+
+ type sym = union
+ `Dcl dcl#
+ `Ucon ucon#
+ ;;
+
+ type tysym = union
+ `Tyfwd
+ `Trfwd
+ `Tydef tydef#
+ `Trdef traitdef#
+ ;;
+
+ type name = struct
+ ns : byte[:]
+ name : byte[:]
+ ;;
+
+ type vis = union
+ `Visintern
+ `Vishidden
+ `Visexport
+ `Visbuiltin
;;
;;
--- a/mparse/util.myr
+++ b/mparse/util.myr
@@ -3,12 +3,34 @@
use "types.use"
pkg parse =
+ const ifmt : (sb : std.strbuf#, ind : int, fmt : byte[:], args : ... -> void)
$noret const err : (loc : srcloc, msg : byte[:], args : ... -> void)
- $noret const verr : (loc : srcloc, msg : byte[:], args : std.valist -> void)
+ $noret const verr : (loc : srcloc, msg : byte[:], args : std.valist# -> void)
;;
const err = {loc, msg, args
+ var ap
+
+ ap = std.vastart(&args)
+ verr(loc, msg, &ap)
}
const verr = {loc, msg, ap
+ var sb, ln
+
+ sb = std.mksb()
+ std.sbfmtv(sb, msg, ap)
+ ln = std.sbfin(sb)
+ std.fatal("{}:{}:{}: {}\n", loc.file, loc.line, loc.col, ln)
+ std.slfree(ln)
+}
+
+const ifmt = {sb, ind, fmt, args : ...
+ var ap
+
+ ap = std.vastart(&args)
+ for var i = 0; i < ind; i++
+ std.sbputs(sb, " ")
+ ;;
+ std.sbfmtv(sb, fmt, &ap)
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -224,8 +224,7 @@
size_t nextlibs;
Node **stmts; /* all top level statements */
size_t nstmts;
- Node
- **init; /* a list of all __init__ function names of our deps. NB, this
+ Node **init; /* a list of all __init__ function names of our deps. NB, this
is a Nname, not an Ndecl */
size_t ninit;
Node *localinit; /* and the local one, if any */
@@ -334,13 +333,6 @@
char isexportinit;
char isinit;
} decl;
-
- struct {
- long uid;
- Node *name;
- Type *elt;
- Type *alt;
- } uelt;
struct {
Stab *scope;
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -645,7 +645,7 @@
continue;
if (c == '.')
isfloat = 1;
- else if (hexval(c) < 0 || hexval(c) > base)
+ else if (hexval(c) < 0 || hexval(c) >= base)
lfatal(curloc, "Integer digit '%c' outside of base %d", c, base);
if (nbuf >= sizeof buf - 1) {
buf[nbuf - 1] = '\0';