include ivylang
include io
include error
include sys
instance env : environment(str)
object ivy = { ...
instance file : file_io(str,str)
action write_file(name:str,buf:str) = {
var ok := file.write(name,buf);
if ~ok {
var ann : annot;
call report_error(cannot_write.make(name),ann);
}
}
var include_path : vector[str]
after init {
var inc := env.get("IVY_INCLUDE_PATH");
var start := inc.begin;
var idx := inc.begin;
while idx < inc.end {
if inc.value(idx) = 58 { # colon
if idx > start {
include_path := include_path.append(inc.segment(start,idx));
};
start := idx.next;
};
idx := idx.next
};
if idx > start {
include_path := include_path.append(inc.segment(start,idx));
}
}
object prog = { ...
type readst = struct {
have_read : ident_set
}
action find_include(name:str) returns (name:str) = {
name := name.extend(".ivy");
if ~file.exist(name) {
var idx := include_path.begin;
var found := false;
while ~found & idx < include_path.end {
var pname := path.concat(include_path.value(idx),name);
if file.exist(pname) {
name := pname;
found := true
};
idx := idx.next;
}
}
}
action read_file_int(name:str,ann:annot,p:prog,rst:readst) returns (p:prog,rst:readst) = {
var text : str;
var ok : bool;
(text,ok) := file.read(name,text);
if ok {
var st := pstate.make(text);
st.ann.file := name;
(st,p) := prog.parse_to(st,0,p);
ok := st.ok & st.tok.end = 0;
if ok {
var idx := p.decls.begin;
while idx < p.decls.end & errors.end = 0 {
var d := p.decls.value(idx);
if d isa includedc {
var sname := d.get_expr;
if ~(sname isa symbol) {
call report_error(bad_syntax.make(sname),sname.get_ann);
} else {
var iname := sname.get_name;
if ~rst.have_read.mem(iname) {
var fname := find_include(iname.to_str);
var subp : prog;
(subp,rst) := read_file_int(fname,d.get_ann,subp,rst);
p.decls := p.decls.set(idx,groupdc.make(subp.decls));
rst.have_read := rst.have_read.set(iname,true);
}
}
};
idx := idx.next
}
} else {
var foo := syntax_error.make(st.tok);
call report_error(foo,st.ann);
}
} else {
var foo := file_not_found.make(name);
call report_error(foo,ann);
}
}
Read the main file, named action read_file(name:str) returns (p:prog) = {
var ann:annot;
p.decls := p.decls.append(includedc.make(symbol.makestr("ivy",ann),ann));
var rst : readst;
(p,rst) := read_file_int(name,ann,p,rst);
}
}
instance path : path_name(str)
}