Lit: fix shows and parser of lit lang

This commit is contained in:
rheidner 2021-09-22 18:18:03 -03:00
parent 6358d1b522
commit 1949e34f7b
2 changed files with 490 additions and 436 deletions

View File

@ -168,11 +168,11 @@ Lit.Core.World.get_func(name: String, world: Lit.Core.World): Maybe<Lit.Core.Bon
} default none
} default none
// Lit.Core.Type.find_ctor(name: String, type: Lit.Core.Type): Maybe<Pair<Nat,Lit.Core.Type.Ctor>>
// case type {
// word: none
// data: List.ifind!((i,f) String.eql(f@name,name), type.ctors)
// }
Lit.Core.Type.find_ctor(name: String, type: Lit.Core.Type): Maybe<Pair<Nat,Lit.Core.Type.Constructor>>
case type {
word: none
data: List.ifind!((i,f) String.eql(f@name,name), type.constructors)
}
// Type-Checking
// -------------

View File

@ -1,68 +1,77 @@
//// A simple syntax for Lit.Core terms. This is NOT part of the protocol.
//
//// Stringifier
//// -----------
//
//Lit.Lang.show.page(page: Lit.Core.Page, world: Lit.Core.World): String
// String.join("\n", List.mapped!(page)!((s) Lit.Lang.show.line(s,world)))
//
//Lit.Lang.show.line(line: Lit.Core.Line, world: Lit.Core.World): String
// case line {
// new_type: Lit.Lang.show.type(line.value, world)
// new_func: Lit.Lang.show.func(line.value, world)
// new_user: Lit.Lang.show.user(line.value, world)
// ext_exec: Lit.Lang.show.exec(line.value, world)
// }
//
//Lit.Lang.show.type.short(type: Lit.Core.Type): String
// case type {
// adt: type.name
// }
//
//Lit.Lang.show.type(type: Lit.Core.Type, world: Lit.Core.World): String
// case type {
// adt:
// "type " | type.name
// | " { "
// | String.join(", ", List.mapped!(type.ctors)!((ctor)
// open ctor
// if List.is_empty!(ctor.fields) then
// ctor.name
// else
// ctor.name
// | "{"
// | String.join(", ", List.mapped!(ctor.fields)!((field)
// open field
// field.name | ": " | field.type
// ))
// | "}"
// ))
// | " }"
// }
//
//Lit.Lang.show.func(func: Lit.Core.Func, world: Lit.Core.World): String
// open func
// case func.ownr {
// nil: ""
// cons: List.show!(Function.id!, func.ownr) | "@"
// }
// | func.name
// | " ( "
// | String.join(",",List.mapped!(List.zip!!(func.iarg,func.ityp))!((x) x@fst|": "|x@snd))
// | " ) : "
// | func.otyp
// | "\n"
// | Lit.Lang.show.term(func.main, world)
//
//Lit.Lang.show.user(user: Lit.Core.User, world: Lit.Core.World): String
// A simple syntax for Lit.Core terms. This is NOT part of the protocol.
// Stringifier
// -----------
Lit.Lang.show.page(page: Lit.Core.Page, world: Lit.Core.World): String
String.join("\n", List.mapped!(page)!((s) Lit.Lang.show.statement(s,world)))
Lit.Lang.show.statement(statement: Lit.Core.Statement, world: Lit.Core.World): String
case statement {
define: Lit.Lang.show.entry(statement.entry, world)
call: Lit.Lang.show.term(statement.expr, world)
}
Lit.Lang.show.entry(
entry: Lit.Core.Entry
world: Lit.Core.World
): String
case entry {
type: Lit.Lang.show.type(entry.value, world)
bond: Lit.Lang.show.bond(entry.value, world)
}
Lit.Lang.show.type.short(type: Lit.Core.Type): String
case type {
word: "U64"
data: type.name
}
Lit.Lang.show.type(type: Lit.Core.Type, world: Lit.Core.World): String
case type {
word: "U64"
data:
"type " | type.name
| " { "
| String.join(", ", List.mapped!(type.constructors)!((ctor)
open ctor
if List.is_empty!(ctor.fields) then
ctor.name
else
ctor.name
| "{"
| String.join(", ", List.mapped!(ctor.fields)!((field)
open field
field.name | ": " | field.type
))
| "}"
))
| " }"
}
Lit.Lang.show.bond(bond: Lit.Core.Bond, world: Lit.Core.World): String
open bond
case bond.owners {
nil: ""
cons: List.show!(Function.id!, bond.owners) | "@"
}
| bond.name
| " ( "
| String.join(",",List.mapped!(List.zip!!(bond.input_names,bond.input_types))!((x) x@fst|": "|x@snd))
| " ) : "
| bond.output_type
| "\n"
| Lit.Lang.show.term(bond.main, world)
// Lit.Lang.show.user(user: Lit.Core.User, world: Lit.Core.World): String
// open user
// "user "
// | user.name
// | " { "
// | user.pkey
// | " }"
//
//Lit.Lang.show.exec(exec: Lit.Core.Exec, world: Lit.Core.World): String
// Lit.Lang.show.exec(exec: Lit.Core.Exec, world: Lit.Core.World): String
// open exec
// "with "
// | exec.user
@ -71,121 +80,164 @@
// | " } signed { "
// | exec.sign
// | " } "
//
//Lit.Lang.show.term(term: Lit.Core.Term, world: Lit.Core.World): String
// case term {
// var: term.name
// create: Maybe {
// get type = Lit.Core.World.get_type(term.type, world)
// case type {
// adt: Maybe {
// get ctor = type.ctors[term.ctor]
// use ctor = ctor
// let text = ""
// let vals = List.zip_with!!!(
// (field,value)
// field@name
// | ":"
// | Lit.Lang.show.term(value, world),
// ctor.fields,
// term.vals)
// let vals = if List.is_empty!(vals) then "" else "{" | String.join(",",vals) | "}"
// return type.name | "/" | ctor.name | vals
// }
// }
// } <> "?"
// match: Maybe {
// get type = Lit.Core.World.get_type(term.type, world)
// case type {
// adt: Maybe {
// let expr = Lit.Lang.show.term(term.expr, world)
// let name = term.name
// let vals = List.zip_with!!!(
// (ctor,cse)
// let fields = List.map!!((x) name | "." | x@name, List.reverse!(ctor@fields))
// ctor@name
// | ": "
// | Lit.Lang.show.term(cse@body, world),
// type.ctors,
// term.cses)
// return "case " | name | " : " | type.name | " = " | expr | " { " | String.join(", ",vals) | " }"
// }
// }
// } <> "?"
// call: Maybe {
// let name = term.name
// let fnam = term.func
// get func = Lit.Core.World.get_func(fnam, world)
// use func = func
// let args = String.join(",",List.mapped!(List.zip!!(func.iarg,term.args))!((x)x@fst|": "|Lit.Lang.show.term(x@snd,world)))
// let cont = Lit.Lang.show.term(term.cont, world)
// return "call " | name | " = " | fnam | "(" | args | "); " | cont
// } <> "?"
// bind: Maybe {
// let name = term.name
// let main = Lit.Lang.show.term(term.main, world)
// let cont = Lit.Lang.show.term(term.cont, world)
// return "bind " | name | " = " | main | " ; " | cont
// } <> "?"
// }// default "?"
//
//// Parser
//// ------
//
//Lit.Lang.parser.page(world: Lit.Core.World): Parser<Lit.Core.Page>
// Parser.choice!([
// Parser {
// get head = Lit.Lang.parser.line(world)
// let world = case head {
// new_type: case head.value {
// adt: world{head.value.name} <- Lit.Core.Entry.type(head.value)
// } default world
// } default world
// get tail = Lit.Lang.parser.page(world)
// return head & tail
// }
// Parser {
// return []
// }
// ])
//
//Lit.Lang.parser.line(world: Lit.Core.World): Parser<Lit.Core.Line>
// Parser.choice!([
// Parser {
// get func = Lit.Lang.parser.func(world)
// return Lit.Core.Line.new_func(func)
// }
// Parser {
// get type = Lit.Lang.parser.type(world)
// return Lit.Core.Line.new_type(type)
// }
// Parser {
// get user = Lit.Lang.parser.user(world)
// return Lit.Core.Line.new_user(user)
// }
// Parser {
// get exec = Lit.Lang.parser.exec(world)
// return Lit.Core.Line.ext_exec(exec)
// }
// ])
//
//Lit.Lang.parser.exec(world: Lit.Core.World): Parser<Lit.Core.Exec>
// Parser {
// Lit.Lang.parser.text("with")
// get user = Lit.Lang.parser.name
// Lit.Lang.parser.text("{")
// get expr = Lit.Lang.parser.term(world)
// Lit.Lang.parser.text("}")
// Lit.Lang.parser.text("signed")
// Lit.Lang.parser.text("{")
// get sign = Lit.Lang.parser.name
// Lit.Lang.parser.text("}")
// Lit.Lang.parser.text(":")
// get otyp = Lit.Lang.parser.name
// return Lit.Core.Exec.new(user, sign, expr, otyp)
// }
//
//Lit.Lang.parser.user(world: Lit.Core.World): Parser<Lit.Core.User>
Lit.Lang.show.term(term: Lit.Core.Term, world: Lit.Core.World): String
case term {
var: term.name
create: Maybe {
get type = Lit.Core.World.get_type(term.type, world)
case type {
word: Maybe { return "U64/new" }
data: Maybe {
get ctor = type.constructors[term.ctor]
use ctor = ctor
let text = ""
let vals = List.zip_with!!!(
(field,value)
field@name
| ":"
| Lit.Lang.show.term(value, world),
ctor.fields,
term.vals)
let vals = if List.is_empty!(vals) then "" else "{" | String.join(",",vals) | "}"
return type.name | "/" | ctor.name | vals
}
}
} <> "CREATE"
match: Maybe {
get type = Lit.Core.World.get_type(term.type, world)
log(term.type)
case type {
word: Maybe {return "U64/new"}
data: Maybe {
let expr = Lit.Lang.show.term(term.expr, world)
let name = term.name
let vals = List.zip_with!!!(
(ctor,cse)
let fields = List.map!!((x) name | "." | x@name, List.reverse!(ctor@fields))
ctor@name
| ": "
| Lit.Lang.show.term(cse@body, world),
type.constructors,
term.cses)
return "case " | name | " : " | type.name | " = " | expr | " { " | String.join(", ",vals) | " }"
}
}
} <> "MATCH"
call: Maybe {
let name = term.name
let fnam = term.func
get func = Lit.Core.World.get_func(fnam, world)
use func = func
let args = String.join(",",List.mapped!(List.zip!!(func.input_names,term.args))!((x)x@fst|": "|Lit.Lang.show.term(x@snd,world)))
let cont = Lit.Lang.show.term(term.cont, world)
return "call " | name | " = " | fnam | "(" | args | "); " | cont
} <> "?"
bind: Maybe {
let name = term.name
let main = Lit.Lang.show.term(term.main, world)
let cont = Lit.Lang.show.term(term.cont, world)
return "bind " | name | " = " | main | " ; " | cont
} <> "?"
word:
U64.show(term.numb)
compare:
"cmp " | Lit.Lang.show.term(term.val0, world) | " " | Lit.Lang.show.term(term.val1, world) | " "
| "{ "
| " ltn: " | Lit.Lang.show.term(term.iflt, world)
| " eql: " | Lit.Lang.show.term(term.ifeq, world)
| " gtn: " | Lit.Lang.show.term(term.ifgt, world)
| " } "
operate:
Lit.Lang.show.term(term.val0, world)
| " "
| Lit.Lang.show.operation(term.oper)
| " "
| Lit.Lang.show.term(term.val1, world)
}
Lit.Lang.show.operation(
operation: Lit.Core.Operation
): String
case operation {
add: "+"
sub: "-"
mul: "*"
div: "/"
mod: "%"
or: "||"
and: "&&"
xor: "^"
}
// Parser
// ------
Lit.Lang.parser.page(world: Lit.Core.World): Parser<Lit.Core.Page>
Parser.choice!([
Parser {
get head = Lit.Lang.parser.statement(world)
let world = case head {
define: case head.entry as entry {
type:
case entry.value {
word: world
data: world{entry.value.name} <- Lit.Core.Entry.type(entry.value)
}
} default world
} default world
get tail = Lit.Lang.parser.page(world)
return head & tail
}
Parser {
return []
}
])
Lit.Lang.parser.statement(world: Lit.Core.World): Parser<Lit.Core.Statement>
Parser.choice!([
Parser {
get entry = Lit.Lang.parser.entry(world)
return Lit.Core.Statement.define(entry)
}
Parser {
get call = Lit.Lang.parser.call(world)
return Lit.Core.Statement.call(call)
}
// Parser {
// get user = Lit.Lang.parser.user(world)
// return Lit.Core.Statement.new_user(user)
// }
// Parser {
// get exec = Lit.Lang.parser.exec(world)
// return Lit.Core.Statement.ext_exec(exec)
// }
])
Lit.Lang.parser.entry(world: Lit.Core.World): Parser<Lit.Core.Entry>
Parser.choice!([
Parser {
get bond = Lit.Lang.parser.bond(world)
return Lit.Core.Entry.bond(bond)
}
Parser {
get type = Lit.Lang.parser.type(world)
return Lit.Core.Entry.type(type)
}
])
Lit.Lang.parser.call(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser {
Lit.Lang.parser.text("do")
Lit.Lang.parser.text("{")
get expr = Lit.Lang.parser.term(world)
Lit.Lang.parser.text("}")
// Lit.Lang.parser.text(":")
// get otyp = Lit.Lang.parser.name
return expr
}
// Lit.Lang.parser.user(world: Lit.Core.World): Parser<Lit.Core.User>
// Parser {
// Lit.Lang.parser.text("user")
// get name = Lit.Lang.parser.name
@ -194,260 +246,262 @@
// Lit.Lang.parser.text("}")
// return Lit.Core.User.new(name, pkey)
// }
//
//Lit.Lang.parser.func(world: Lit.Core.World): Parser<Lit.Core.Func>
// Parser {
// get ownr = Parser.maybe!(Parser {
// get names = Parser.until!(Lit.Lang.parser.text("@"), Parser {
// get names = Lit.Lang.parser.name
// Parser.maybe!(Kind.Parser.text(","))
// return names
// })
// return names
// })
// let ownr = ownr <> []
// get name = Lit.Lang.parser.name
// get args = Parser.wrap!(
// Lit.Lang.parser.text("("),
// Lit.Lang.parser.bind(world),
// Lit.Lang.parser.text(")"));
// let iarg = List.mapped!(args)!((x) x@fst)
// let ityp = List.mapped!(args)!((x) x@snd)
// Lit.Lang.parser.text(":")
// get otyp = Lit.Lang.parser.name
// get main = Lit.Lang.parser.term(world)
// return Lit.Core.Func.new(name, ownr, main, iarg, ityp, otyp)
// }
//
//Lit.Lang.parser.type(world: Lit.Core.World): Parser<Lit.Core.Type>
// Parser {
// Lit.Lang.parser.text("type")
// get name = Lit.Lang.parser.name
// get ctors = Parser.wrap!(
// Lit.Lang.parser.text("{")
// Parser {
// Parser.maybe!(Lit.Lang.parser.text(","))
// Lit.Lang.parser.type.ctor(world)
// }
// Lit.Lang.parser.text("}")
// )
// return Lit.Core.Type.adt(name, ctors)
// }
//
//Lit.Lang.parser.type.ctor(world: Lit.Core.World): Parser<Lit.Core.Type.Ctor>
// Parser {
// get name = Lit.Lang.parser.name
// get fields = Parser.choice!([
// Parser.wrap!(
// Lit.Lang.parser.text("{")
// Parser {
// Parser.maybe!(Lit.Lang.parser.text(","))
// get name = Lit.Lang.parser.name
// Lit.Lang.parser.text(":")
// get type = Lit.Lang.parser.name
// return Lit.Core.Type.Field.new(name, type)
// }
// Lit.Lang.parser.text("}")
// )
// Parser {
// return []
// }
// ])
// return Lit.Core.Type.Ctor.new(name, fields)
// }
//
//Lit.Lang.parser.term(world: Lit.Core.World): Parser<Lit.Core.Term>
// Parser.choice!([
// Lit.Lang.parser.term.create(world)
// Lit.Lang.parser.term.match(world)
// Lit.Lang.parser.term.bind(world)
// Lit.Lang.parser.term.call(world)
// Lit.Lang.parser.term.var(world)
// ])
//
//Lit.Lang.parser.term.create(world: Lit.Core.World): Parser<Lit.Core.Term>
// Parser {
// get type_name = Lit.Lang.parser.name
// case Lit.Core.World.get_type(type_name, world) as found {
// none: Parser.fail!("Type not found.")
// some: Parser {
// Lit.Lang.parser.text("/")
// get ctor_name = Lit.Lang.parser.name
// use type = found.value
// case Lit.Core.Type.find_ctor(ctor_name, type) as found {
// none: Parser.fail!("Ctor not found.")
// some: Parser {
// let {ctor_num, ctor} = found.value
// let fields = ctor@fields
// if List.is_empty!(fields) then Parser {
// return Lit.Core.Term.create(type_name, ctor_num, [])
// } else Parser {
// let fields = List.map!!((x) x@name, fields)
// Lit.Lang.parser.text("{")
// get vals = Lit.Lang.parser.term.args(fields, world)
// Lit.Lang.parser.text("}")
// return Lit.Core.Term.create(type_name, ctor_num, vals)
// }
// }
// }
// }
// }
// }
//
//Lit.Lang.parser.bind(world: Lit.Core.World): Parser<Pair<String,String>>
// Parser {
// get name = Lit.Lang.parser.name
// Lit.Lang.parser.text(":")
// get type = Lit.Lang.parser.name
// Parser.maybe!(Lit.Lang.parser.text(","))
// return {name, type}
// }
//
//Lit.Lang.parser.term.args(fields: List<String>, world: Lit.Core.World): Parser<List<Lit.Core.Term>>
// case fields {
// nil: Parser {
// return []
// }
// cons: Parser {
// Lit.Lang.parser.text(fields.head)
// Lit.Lang.parser.text(":")
// get head = Lit.Lang.parser.term(world)
// Parser.maybe!(Lit.Lang.parser.text(","))
// get tail = Lit.Lang.parser.term.args(fields.tail, world)
// return head & tail
// }
// }
//
//Lit.Lang.parser.term.match(world: Lit.Core.World): Parser<Lit.Core.Term>
// Parser {
// Lit.Lang.parser.text("case ")
// get name = Lit.Lang.parser.name
// Lit.Lang.parser.text(":")
// get type_name = Lit.Lang.parser.name
// case Lit.Core.World.get_type(type_name, world) as found {
// none: Parser.fail!("Type not found.")
// some: Parser {
// let type = found.value
// case type {
// adt: Parser {
// get expr = Parser.choice!([
// Parser {
// Lit.Lang.parser.text("=")
// Lit.Lang.parser.term(world)
// }
// Parser {
// return Lit.Core.Term.var(name)
// }
// ])
// Lit.Lang.parser.text("{")
// get cses = Lit.Lang.parser.term.match.cses(type.ctors, name, world)
// Lit.Lang.parser.text("}")
// return Lit.Core.Term.match(type_name, name, expr, cses)
// }
// }
// }
// }
// }
//
//Lit.Lang.parser.term.match.cses(cses: List<Lit.Core.Type.Ctor>, name: String, world: Lit.Core.World): Parser<List<Lit.Core.Term.Case>>
// case cses {
// nil: Parser {
// return []
// }
// cons: Parser {
// use ctor = cses.head
// Lit.Lang.parser.text(ctor.name)
// Lit.Lang.parser.text(":")
// let fields = List.map!!((x) name | "." | x@name, List.reverse!(ctor.fields))
// get term = Lit.Lang.parser.term(world)
// let head = Lit.Core.Term.Case.new(fields, term)
// Parser.maybe!(Lit.Lang.parser.text(","))
// get tail = Lit.Lang.parser.term.match.cses(cses.tail, name, world)
// return head & tail
// }
// }
//
//Lit.Lang.parser.term.var(world: Lit.Core.World): Parser<Lit.Core.Term>
// Parser {
// get name = Lit.Lang.parser.name
// return Lit.Core.Term.var(name)
// }
//
//Lit.Lang.parser.term.call(world: Lit.Core.World): Parser<Lit.Core.Term>
// Parser {
// Lit.Lang.parser.text("call ")
// get name = Lit.Lang.parser.name
// Lit.Lang.parser.text("=")
// get fnam = Lit.Lang.parser.name
// Lit.Lang.parser.text("(")
// get args = Parser.many!(Parser {
// get term = Lit.Lang.parser.term(world)
// Parser.maybe!(Lit.Lang.parser.text(","))
// return term
// })
// Lit.Lang.parser.text(")")
// Parser.maybe!(Lit.Lang.parser.text(";"))
// get cont = Lit.Lang.parser.term(world)
// return Lit.Core.Term.call(name, fnam, args, cont)
// }
//
//Lit.Lang.parser.term.bind(world: Lit.Core.World): Parser<Lit.Core.Term>
// Parser {
// Lit.Lang.parser.text("bind ")
// get name = Lit.Lang.parser.name
// Lit.Lang.parser.text("=")
// get main = Lit.Lang.parser.term(world)
// Parser.maybe!(Lit.Lang.parser.text(";"))
// get cont = Lit.Lang.parser.term(world)
// return Lit.Core.Term.bind(name, main, cont)
// }
//
//Lit.Lang.parser.text(text: String): Parser(Unit)
// Parser {
// Lit.Lang.parser.ignore
// Parser.text(text)
// }
//
//Lit.Lang.parser.ignore: Parser(List<Unit>)
// Parser.many!(Parser.choice!([
// Parser.text(" ")
// Parser.text("\t")
// Parser.text("\r")
// Parser.text("\n")
// Parser {
// Parser.text("//")
// let end = Parser.choice!([Parser.text("\n"), Parser.eof])
// Parser.until!(end, Parser.one)
// return unit
// }
// ]))
//
//Lit.Lang.parser.name: Parser<String>
// Parser {
// Lit.Lang.parser.ignore
// get chrs = Parser.many1<Kind.Letter>(Lit.Lang.parser.letter)
// return List.fold!(chrs)!(String.nil, String.cons)
// }
//
//Lit.Lang.parser.letter: Parser(Kind.Letter)
// (pst)
// open pst
// case pst.str {
// nil:
// Parser.Reply.fail!(pst.nam, pst.ini, pst.idx, "Unexpected eof."),
// cons:
// if Lit.Lang.parser.is_letter(pst.str.head) then
// let pst = Parser.State.new(pst.err, pst.nam, pst.ini, Nat.succ(pst.idx), pst.str.tail)
// Parser.Reply.value!(pst, pst.str.head)
// else
// Parser.Reply.fail!(pst.nam, pst.ini, pst.idx, "Expected name."),
// }
//
//Lit.Lang.parser.is_letter(chr: Char): Bool
// if U16.btw('A', chr, 'Z') then Bool.true
// else if U16.btw('a', chr, 'z') then Bool.true
// else if U16.btw('0', chr, '9') then Bool.true
// else if U16.eql('.', chr) then Bool.true
// else if U16.eql('_', chr) then Bool.true
// else if U16.eql('^', chr) then Bool.true
// else Bool.false
Lit.Lang.parser.bond(world: Lit.Core.World): Parser<Lit.Core.Bond>
Parser {
get ownr = Parser.maybe!(Parser {
get names = Parser.until!(Lit.Lang.parser.text("@"), Parser {
get names = Lit.Lang.parser.name
Parser.maybe!(Kind.Parser.text(","))
return names
})
return names
})
let ownr = ownr <> []
get name = Lit.Lang.parser.name
get args = Parser.wrap!(
Lit.Lang.parser.text("("),
Lit.Lang.parser.bind(world),
Lit.Lang.parser.text(")"));
let iarg = List.mapped!(args)!((x) x@fst)
let ityp = List.mapped!(args)!((x) x@snd)
Lit.Lang.parser.text(":")
get otyp = Lit.Lang.parser.name
get main = Lit.Lang.parser.term(world)
return Lit.Core.Bond.new(name, ownr, main, iarg, ityp, otyp)
}
Lit.Lang.parser.type(world: Lit.Core.World): Parser<Lit.Core.Type>
Parser {
Lit.Lang.parser.text("type")
get name = Lit.Lang.parser.name
get ctors = Parser.wrap!(
Lit.Lang.parser.text("{")
Parser {
Parser.maybe!(Lit.Lang.parser.text(","))
Lit.Lang.parser.type.constructor(world)
}
Lit.Lang.parser.text("}")
)
return Lit.Core.Type.data(name, ctors)
}
Lit.Lang.parser.type.constructor(world: Lit.Core.World): Parser<Lit.Core.Type.Constructor>
Parser {
get name = Lit.Lang.parser.name
get fields = Parser.choice!([
Parser.wrap!(
Lit.Lang.parser.text("{")
Parser {
Parser.maybe!(Lit.Lang.parser.text(","))
get name = Lit.Lang.parser.name
Lit.Lang.parser.text(":")
get type = Lit.Lang.parser.name
return Lit.Core.Type.Field.new(name, type)
}
Lit.Lang.parser.text("}")
)
Parser {
return []
}
])
return Lit.Core.Type.Constructor.new(name, fields)
}
Lit.Lang.parser.term(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser.choice!([
Lit.Lang.parser.term.create(world)
Lit.Lang.parser.term.match(world)
Lit.Lang.parser.term.bind(world)
Lit.Lang.parser.term.call(world)
Lit.Lang.parser.term.var(world)
])
Lit.Lang.parser.term.create(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser {
get type_name = Lit.Lang.parser.name
case Lit.Core.World.get_type(type_name, world) as found {
none: Parser.fail!("Type not found.")
some: Parser {
Lit.Lang.parser.text("/")
get ctor_name = Lit.Lang.parser.name
use type = found.value
case Lit.Core.Type.find_ctor(ctor_name, type) as found {
none: Parser.fail!("Ctor not found.")
some: Parser {
let {ctor_num, ctor} = found.value
let fields = ctor@fields
if List.is_empty!(fields) then Parser {
return Lit.Core.Term.create(type_name, ctor_num, [])
} else Parser {
let fields = List.map!!((x) x@name, fields)
Lit.Lang.parser.text("{")
get vals = Lit.Lang.parser.term.args(fields, world)
Lit.Lang.parser.text("}")
return Lit.Core.Term.create(type_name, ctor_num, vals)
}
}
}
}
}
}
Lit.Lang.parser.bind(world: Lit.Core.World): Parser<Pair<String,String>>
Parser {
get name = Lit.Lang.parser.name
Lit.Lang.parser.text(":")
get type = Lit.Lang.parser.name
Parser.maybe!(Lit.Lang.parser.text(","))
return {name, type}
}
Lit.Lang.parser.term.args(fields: List<String>, world: Lit.Core.World): Parser<List<Lit.Core.Term>>
case fields {
nil: Parser {
return []
}
cons: Parser {
Lit.Lang.parser.text(fields.head)
Lit.Lang.parser.text(":")
get head = Lit.Lang.parser.term(world)
Parser.maybe!(Lit.Lang.parser.text(","))
get tail = Lit.Lang.parser.term.args(fields.tail, world)
return head & tail
}
}
Lit.Lang.parser.term.match(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser {
Lit.Lang.parser.text("case ")
get name = Lit.Lang.parser.name
Lit.Lang.parser.text(":")
get type_name = Lit.Lang.parser.name
case Lit.Core.World.get_type(type_name, world) as found {
none: Parser.fail!("Type not found.")
some: Parser {
let type = found.value
case type {
word: Parser.fail!("Can't pattern match word's")
data: Parser {
get expr = Parser.choice!([
Parser {
Lit.Lang.parser.text("=")
Lit.Lang.parser.term(world)
}
Parser {
return Lit.Core.Term.var(name)
}
])
Lit.Lang.parser.text("{")
get cses = Lit.Lang.parser.term.match.cses(type.constructors, name, world)
Lit.Lang.parser.text("}")
return Lit.Core.Term.match(type_name, name, expr, cses)
}
}
}
}
}
Lit.Lang.parser.term.match.cses(cses: List<Lit.Core.Type.Constructor>, name: String, world: Lit.Core.World): Parser<List<Lit.Core.Term.Case>>
case cses {
nil: Parser {
return []
}
cons: Parser {
use ctor = cses.head
Lit.Lang.parser.text(ctor.name)
Lit.Lang.parser.text(":")
let fields = List.map!!((x) name | "." | x@name, List.reverse!(ctor.fields))
get term = Lit.Lang.parser.term(world)
let head = Lit.Core.Term.Case.new(fields, term)
Parser.maybe!(Lit.Lang.parser.text(","))
get tail = Lit.Lang.parser.term.match.cses(cses.tail, name, world)
return head & tail
}
}
Lit.Lang.parser.term.var(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser {
get name = Lit.Lang.parser.name
return Lit.Core.Term.var(name)
}
Lit.Lang.parser.term.call(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser {
Lit.Lang.parser.text("call ")
get name = Lit.Lang.parser.name
Lit.Lang.parser.text("=")
get fnam = Lit.Lang.parser.name
Lit.Lang.parser.text("(")
get args = Parser.many!(Parser {
get term = Lit.Lang.parser.term(world)
Parser.maybe!(Lit.Lang.parser.text(","))
return term
})
Lit.Lang.parser.text(")")
Parser.maybe!(Lit.Lang.parser.text(";"))
get cont = Lit.Lang.parser.term(world)
return Lit.Core.Term.call(name, fnam, args, cont)
}
Lit.Lang.parser.term.bind(world: Lit.Core.World): Parser<Lit.Core.Term>
Parser {
Lit.Lang.parser.text("bind ")
get name = Lit.Lang.parser.name
Lit.Lang.parser.text("=")
get main = Lit.Lang.parser.term(world)
Parser.maybe!(Lit.Lang.parser.text(";"))
get cont = Lit.Lang.parser.term(world)
return Lit.Core.Term.bind(name, main, cont)
}
Lit.Lang.parser.text(text: String): Parser(Unit)
Parser {
Lit.Lang.parser.ignore
Parser.text(text)
}
Lit.Lang.parser.ignore: Parser(List<Unit>)
Parser.many!(Parser.choice!([
Parser.text(" ")
Parser.text("\t")
Parser.text("\r")
Parser.text("\n")
Parser {
Parser.text("//")
let end = Parser.choice!([Parser.text("\n"), Parser.eof])
Parser.until!(end, Parser.one)
return unit
}
]))
Lit.Lang.parser.name: Parser<String>
Parser {
Lit.Lang.parser.ignore
get chrs = Parser.many1<Kind.Letter>(Lit.Lang.parser.letter)
return List.fold!(chrs)!(String.nil, String.cons)
}
Lit.Lang.parser.letter: Parser(Kind.Letter)
(pst)
open pst
case pst.str {
nil:
Parser.Reply.fail!(pst.nam, pst.ini, pst.idx, "Unexpected eof."),
cons:
if Lit.Lang.parser.is_letter(pst.str.head) then
let pst = Parser.State.new(pst.err, pst.nam, pst.ini, Nat.succ(pst.idx), pst.str.tail)
Parser.Reply.value!(pst, pst.str.head)
else
Parser.Reply.fail!(pst.nam, pst.ini, pst.idx, "Expected name."),
}
Lit.Lang.parser.is_letter(chr: Char): Bool
if U16.btw('A', chr, 'Z') then Bool.true
else if U16.btw('a', chr, 'z') then Bool.true
else if U16.btw('0', chr, '9') then Bool.true
else if U16.eql('.', chr) then Bool.true
else if U16.eql('_', chr) then Bool.true
else if U16.eql('^', chr) then Bool.true
else Bool.false