Ast2
include lang
object ivy = {
instantiate verb_base
instantiate expr_base
instantiate stmt_base(expr,":=",false)
instantiate decl_base(expr,stmt)
object stmt = { ...
object varst = {
variant this of stmt = struct {
name : expr,
ann : annot
}
action make (name:expr,ann:annot) returns (res:stmt) = {
var s:this;
s.name := name;
s.ann := ann;
res := s;
}
action encode(s:this,b:pretty,prio:verb) returns (b:pretty) = {
b := s.ann.encode(b);
if 0 < prio {
b := b.nest;
b := b.extend("{");
b := b.newline;
};
b := s.ann.encode(b);
b := b.nest;
b := b.extend("var");
b := b.extend(" ");
b := s.name.encode(b,0);
b := b.extend(";");
b := b.unnest;
if 1 < prio {
b := b.unnest;
b := b.newline;
b := b.extend("}");
};
}
}
action parse_lang_stmt(st : pstate, prio:verb) returns(st : pstate, res:stmt) = {
if st.tok = "var" {
st := st.consume;
var s : varst;
(st,s.ann) := st.get_ann;
(st,s.name) := expr.parse(st,0);
if st.ok & st.tok = ";" {
st := st.consume;
} else {
st.ok := st.tok = "}"; # allow to omit final semicolon
};
res := s;
} else {
var s : asgn;
(st,s.ann) := st.get_ann;
(st,s.lhs) := expr.parse(st,3);
if st.ok & st.tok = ":=" {
st := st.consume;
(st,s.rhs) := expr.parse(st,0);
if st.ok & st.tok = ";" {
st := st.consume;
} else {
st.ok := st.tok = "}"; # allow to omit final semicolon
}
}
else {
st.ok := false;
};
res := s;
}
}
}
object groupdc = {
variant this of decl = struct {
decls : vector[decl]
}
action make(decls : vector[decl]) returns (res:decl) =
{
var s:this;
s.decls := decls;
res := s;
}
action encode(s:this,b:pretty,prio:verb) returns (b:pretty) = {
b := b.nest;
b := b.extend("{");
var idx := s.decls.begin;
while idx < s.decls.end {
b := b.newline;
b := s.decls.value(0).encode(b,0);
idx := idx.next;
};
b := b.unnest;
b := b.newline;
b := b.extend("}");
}
}
object decl = { ...
action parse(st : pstate, prio:verb) returns(st : pstate, res:decl) = {
if st.tok = "{" {
st := st.consume;
var s : groupdc;
(st,s.decls) := parse_list(st,0);
if st.tok = "}" {
st := st.consume;
} else {st.ok := false};
res := s
}
else if st.tok = "action" {
st := st.consume;
var s : actdc;
(st,s.name) := expr.parse(st,0);
if st.ok & st.tok = "(" {
(st,s.inputs) := expr.tup.parse(st,0);
};
if st.ok & st.tok = "returns" {
st := st.consume;
(st,s.outputs) := expr.tup.parse(st,0);
};
if st.ok & st.tok = "=" {
st := st.consume;
if st.tok = "{" {
(st,s.body) := stmt.parse(st,1);
} else {st.ok := false}
} else {st.ok := false};
res := s
} else {st.ok := false}
}
action parse_list(st : pstate, prio:verb) returns(st : pstate, res:vector[decl]) = {
while st.ok & st.tok.end > 0 & st.tok ~= "}" {
var s : decl;
(st,s) := parse(st,0);
res := res.append(s);
}
}
}
}
export ivy.expr.enc
export ivy.expr.dec
export ivy.expr.encdec
export ivy.stmt.enc
export ivy.stmt.dec
export ivy.stmt.encdec
export ivy.decl.enc
export ivy.decl.dec
export ivy.decl.encdec
import parse_error
export pretty.make
export pretty.extend
export pretty.flush
action pr(max:pos,s:str) returns (res:str) = {
var p := pretty.make(max,4);
var st := pstate.make(s);
while st.tok.end > 0 {
if st.tok = "(" {
p := p.nest
};
p := p.extend(st.tok);
if st.tok = ")" {
p := p.unnest
};
if st.b.value(st.p) = 32 {
p := p.extend(" ");
};
st := st.consume
};
p := p.flush;
res := p.output
}
export pr
var p := pretty.make(11,4);
var st := pstate.make("fooooooo + (bar + baaaaaz)");
while st.tok.end > 0 {
if st.tok = "(" {
p := p.nest
};
p := p.extend(st.tok);
if st.tok = ")" {
p := p.unnest
};
call show_pretty(p);
if st.b.value(st.p) = 32 {
p := p.extend(" ");
call show_pretty(p);
};
st := st.consume
};
p := p.flush;
call show_pretty(p);
}
import action show_pretty(p:pretty)