recursive Kind2 file loader works now...

someone acquired debt today
This commit is contained in:
Victor Taelin 2024-02-22 23:43:20 -03:00
parent ab98950f50
commit cc0bffb22c
11 changed files with 237 additions and 286 deletions

1
book/B.kind2 Normal file
View File

@ -0,0 +1 @@
B = *

View File

@ -9,26 +9,25 @@ BBT.set
= λK λV λcmp λkey λval λmap
let P = λx ∀(key: K) ∀(val: V) (BBT K V)
let bin = λsize λnext.key λnext.val λnext.lft λnext.rgt λkey λval
let P = λx ∀(key: K) ∀(next.key: K) ∀(next.val: V) ∀(next.lft: (BBT K V)) ∀(next.rgt: (BBT K V)) (BBT K V)
let P = λx ∀(key: K) ∀(next.key: K) ∀(next.val: V) ∀(next.lft: (BBT K V)) ∀(next.rgt: (BBT K V)) ∀(key: K) ∀(val: V) (BBT K V)
// Go left
let ltn = λkey λnext.key λnext.val λnext.lft λnext.rgt
let ltn = λkey λnext.key λnext.val λnext.lft λnext.rgt λkey λval
let new_lft = (BBT.set K V cmp key val next.lft)
(BBT.balance K V cmp key next.key next.val new_lft next.rgt)
// Same key, update value
// Should we update the value or return the same tree?
let eql = λkey λnext.key λnext.val λnext.lft λnext.rgt
let eql = λkey λnext.key λnext.val λnext.lft λnext.rgt λkey λval
(BBT.bin K V size next.key val next.lft next.rgt)
// Go right
let gtn = λkey λnext.key λnext.val λnext.lft λnext.rgt
let gtn = λkey λnext.key λnext.val λnext.lft λnext.rgt λkey λval
let new_rgt = (BBT.set K V cmp key val next.rgt)
(BBT.balance K V cmp key next.key next.val next.lft new_rgt)
((~(cmp key next.key) P ltn eql gtn) key next.key next.val next.lft next.rgt)
((~(cmp key next.key) P ltn eql gtn) key next.key next.val next.lft next.rgt key val)
// Empty tree, create new node
let tip = λkey λval
(BBT.singleton K V key val)
((~map P bin tip) key val)

95
book/IO.kind2 Normal file
View File

@ -0,0 +1,95 @@
IO
: ∀(A: *) *
= λA
$self
∀(P: ∀(x: (IO A)) *)
∀(print: ∀(text: String) ∀(then: ∀(x: Unit) (IO A)) (P (IO.print A text then)))
∀(load: ∀(file: String) ∀(then: ∀(x: String) (IO A)) (P (IO.load A file then)))
∀(save: ∀(file: String) ∀(data: String) ∀(then: ∀(x: Unit) (IO A)) (P (IO.save A file data then)))
∀(done: ∀(term: A) (P (IO.done A term)))
(P self)
IO.print
: ∀(A: *)
∀(text: String)
∀(then: ∀(x: Unit) (IO A))
(IO A)
= λA λtext λthen
~λP λprint λload λsave λdone
(print text then)
IO.load
: ∀(A: *)
∀(file: String)
∀(then: ∀(x: String) (IO A))
(IO A)
= λA λfile λthen
~λP λprint λload λsave λdone
(load file then)
IO.save
: ∀(A: *)
∀(file: String)
∀(data: String)
∀(then: ∀(x: Unit) (IO A))
(IO A)
= λA λfile λdata λthen
~λP λprint λload λsave λdone
(save file data then)
IO.done
: ∀(A: *)
∀(term: A)
(IO A)
= λA λterm
~λP λprint λload λsave λdone
(done term)
IO.run
: ∀(A: *)
∀(x: (IO A))
(IO A)
= λA λx
let P = λx(A)
let print = λtext λthen (HVM.print A text (IO.run A (then Unit.one)))
let load = λfile λthen (HVM.load A file λs(IO.run A (then s)))
let save = λfile λdata λthen (HVM.save A file data (IO.run A (then Unit.one)))
let done = λterm (IO.done A term)
(~x P print load save done)
IO.print.do
: ∀(text: String)
(IO Unit)
= λtext
(IO.print Unit text λx
(IO.done Unit x))
IO.load.do
: ∀(file: String)
(IO String)
= λfile
(IO.load String file λx
(IO.done String x))
IO.save.do
: ∀(file: String)
∀(data: String)
(IO Unit)
= λfile λdata
(IO.save Unit file data λx
(IO.done Unit x))
IO.bind
: ∀(A: *)
∀(B: *)
∀(a: (IO A))
∀(b: ∀(x: A) (IO B))
(IO B)
= λA λB λa λb
let P = λx ∀(b: ∀(x: A) (IO B)) (IO B)
let print = λtext λthen λb (IO.print B text λx(IO.bind A B (then x) b))
let load = λfile λthen λb (IO.load B file λs(IO.bind A B (then s) b))
let save = λfile λdata λthen λb (IO.save B file data λx(IO.bind A B (then Unit.one) b))
let done = λterm λb (b term)
((~a P print load save done) b)

View File

@ -22,4 +22,4 @@ Kind.if.app
let txt = λlit λY λN (N (Kind.txt lit))
let hol = λnam λctx λY λN (N (Kind.hol nam ctx))
let var = λnam λidx λY λN (N (Kind.var nam idx))
(~term P all lam app ann slf ins ref def set u60 num op2 mat txt hol var Y N)
(~term P all lam app ann slf ins ref def set u60 num op2 mat txt hol var Y N)

View File

@ -4,4 +4,4 @@ Kind.lam
Kind.Term
= λnam λbod
~λP λall λlam λapp λann λslf λins λref λdef λset λu60 λnum λop2 λmat λtxt λhol λvar
(lam nam bod)
(lam nam bod)

View File

@ -1,118 +1,70 @@
Kind.load
: ∀(name: String)
(IO Kind.Book)
= λname
let book = (String.Map.new Kind.Term)
(Kind.load.name name book)
//// TODO
//Kind.load
// Loads a file into a book
Kind.load.code
: ∀(name: String)
(IO Kind.Book)
= λname
(IO.load Kind.Book (String.concat name ".kind2") λdata
(IO.bind Unit Kind.Book (IO.print.do data) λx
(IO.done Kind.Book (Kind.Book.parse data))))
// Loads a name into a book; then, load its dependencies
Kind.load.name
: ∀(name: String)
∀(book: Kind.Book)
(IO Kind.Book)
= λname λbook
(IO.bind Unit Kind.Book (IO.print.do (String.concat "LOAD:" name)) λx
(IO.bind Kind.Book Kind.Book (Kind.load.code name) λfile
let defs = (String.Map.to_list Kind.Term file)
let fold = (List.fold (Pair String Kind.Term) defs)
let set2 = λnam λval (String.Map.set Kind.Term nam val book)
let setP = λdef λbook (~def λx(Kind.Book) set2)
let book = (fold Kind.Book setP book)
let deps = (Kind.Book.get_refs file)
(Kind.load.dependencies deps book)))
// Loads a list of dependencies
Kind.load.dependencies
: ∀(deps: (List String))
∀(book: Kind.Book)
(IO Kind.Book)
= λdeps λbook
let P = λx ∀(book: Kind.Book) (IO Kind.Book)
let cons = λdeps.head λdeps.tail λbook
(IO.bind Kind.Book Kind.Book (Kind.load.dependency deps.head book) λbook
(Kind.load.dependencies deps.tail book))
let nil = λbook (IO.done Kind.Book book)
((~deps P cons nil) book)
// Loads a single dependency, if not present
// FIXME: String.map.has.linear is removing the entry
Kind.load.dependency
: ∀(name: String)
∀(book: Kind.Book)
(IO Kind.Book)
= λname λbook
let has = (String.Map.has Kind.Term name book)
let P = λx ∀(book: Kind.Book) (IO Kind.Book)
let true = λbook (IO.done Kind.Book book)
let false = λbook (Kind.load.name name book)
((~has P true false) book)
//Kind.load.dependency
//: ∀(name: String)
//Kind.Book
//= λname
//(Kind.load.name #5 name (String.Map.new Kind.Term))
//// Gets the source file of a definition
//Kind.load.file_of
//: ∀(name: String)
//String
//= λname
//(String.concat name ".kind2")
//// Loads a file into a new book
//Kind.load.file
//: ∀(file: String)
//Kind.Book
//= λfile
//(HVM.load Kind.Book file λdata
//(Kind.Book.parse data))
//// Loads a name into a book
//Kind.load.name
//: ∀(lims: #U60)
//∀(name: String)
//∀(book: Kind.Book)
//Kind.Book
//= λlims
//(HVM.log #U60 ∀(name:String)∀(book:Kind.Book)Kind.Book lims
//#match lims = lims {
//#0: λname λbook book
//#+: λname λbook
//(HVM.print Kind.Book (String.concat "LOAD:" name)
//// Checks if name is already on book
//let P = λx (Kind.Book)
//let new = λhas λbook
//// If it is, do nothing; otherwise, define it
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let true = λbook
//(HVM.print Kind.Book (String.concat (String.concat "OLD!:" name) (String.concat " -- " (Kind.keys book))) book)
//let false = λbook
//(HVM.print Kind.Book (String.concat (String.concat "NEW!:" name) (String.concat " -- " (Kind.keys book)))
//let file = (Kind.load.file (Kind.load.file_of name))
//let defs = (String.Map.to_list Kind.Term file)
//let bok1 = (Kind.load.define defs book)
//let file = (Kind.load.file (Kind.load.file_of name))
//let refs = (Kind.Book.get_refs file)
//let bok2 = (HVM.print ?a (String.concat "REC!:" (Kind.keys bok1)) (Kind.load.name.many lims-1 refs bok1))
//bok2)
////(HVM.print.many Kind.Book refs book)
//((~has P true false) book)
//(~(String.Map.has.linear Kind.Term name book) P new))
//}: ∀(name: String) ∀(book: Kind.Book) Kind.Book)
//// Loads many names into a book
//Kind.load.name.many
//: ∀(lims: #U60)
//∀(list: (List String))
//∀(book: Kind.Book)
//Kind.Book
//= λlims λlist λbook
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let cons = λhead λtail λbook
////(HVM.print Kind.Book
////(String.concat "DEP:"
////(String.concat head
////(String.concat " BOOK:"
////(Kind.Book.show book))))
//let bok2 = (Kind.load.name lims head book)
//(Kind.load.name.many lims tail bok2)
//let nil = λbook book
//((~list P cons nil) book)
//// Defines a term and loads its dependencies
////Kind.load.define
////: ∀(name: String)
////∀(term: Kind.Term)
////∀(book: Kind.Book)
////Kind.Book
////= λname λterm λbook
////let book = (String.Map.set Kind.Term name term book)
////let refs = (Kind.Term.get_refs term)
////let book = (Kind.load.name.many refs book)
////book
//// Defines many terms
//Kind.load.define
//: ∀(defs: (List (Pair String Kind.Term)))
//∀(book: Kind.Book)
//Kind.Book
//= λdefs λbook
//// If defs list isn't empty...
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let cons = λdefs.head λdefs.tail λbook
//// Gets the def name/term
//let P = λx (Kind.Book)
//let new = λname λterm
//// Writes it to the book
//let bok2 = (String.Map.set Kind.Term name term book)
//(HVM.print Kind.Book (String.concat "DEF!:" name)
//// Recurses
//(Kind.load.define defs.tail bok2))
//(~defs.head P new)
//// If defs list is empty, return the book
//let nil = λbook book
//((~defs P cons nil) book)
//Kind.keys
//: ∀(book: Kind.Book)
//String
//= λbook
//let defs = (String.Map.to_list Kind.Term book)
//let defs = (List.app (Pair String Kind.Term) String (Pair.fst String Kind.Term) defs)
//(String.join defs)
//(IO Kind.Book)
//= λname λbook
//let P = λx (IO Kind.Book)
//let new = λhas λbook
//let P = λx ∀(book: Kind.Book) (IO Kind.Book)
//let true = λbook (IO.done Kind.Book book)
//let false = λbook (Kind.load.name name book)
//((~has P true false) book)
//(~(String.Map.has.linear Kind.Term name book) P new)

View File

@ -1,3 +1,13 @@
Main
: (IO Unit)
= (IO.run Unit
(IO.bind Unit Unit (IO.print.do "hello") λx
(IO.bind Kind.Book Unit (Kind.load "Bool") λbook
(IO.bind Unit Unit (IO.print.do (Kind.Book.show book)) λx
(IO.done Unit Unit.one)))))
//Main = Kind.load.dependency
//Main
//: Unit
//= let map = (String.Map.new Unit)
@ -8,12 +18,45 @@
//Unit.one)
//Main
//: Unit
//: (IO Unit)
//= (IO.run Unit
//(IO.load Unit "B.kind2" λfile
//(IO.print Unit file λx
//(IO.done Unit Unit.one))))
//FOO
//: Kind.Book
//= (HVM.load Kind.Book "B.kind2" λdata (Kind.Book.parse data))
//Main
//: (String.Map Kind.Book)
//=
////(HVM.load ?k "B.kind2" λcode
////let book = (Kind.Book.parse code)
//let book = (HVM.load ?k "B.kind2" λdata (Kind.Book.parse data))
//let seen = (String.Map.new Kind.Book)
//let seen = (String.Map.set Kind.Book "Bool" book seen)
//seen
////)
//Main
//: (String.Map Unit)
//= let unit = Unit.one
//let seen = (String.Map.new Unit)
//let seen = (String.Map.set Unit "Bool" unit seen)
//seen
//: (String.Map Kind.Book)
//= let book = (Kind.load "Bool")
//book
//(HVM.print Unit (Kind.Book.show book)
//Unit.one)
//Main = Kind.load.name
//Main = Kind.load.code
//Main = Kind.load.go.defs

View File

@ -7,7 +7,7 @@
(Str.view str) = (str 0 λhλt(String.cons h (Str.view t)) String.nil)
(Strs.view strs) = (List.view λx(Str.view x) strs)
(List.view elem list) = (list 0 λhλt(List.cons (elem h) (List.view elem t)) List.nil)
`
Book.A.match = λ_a λ_P λ_t ((_a _P) λ_tag (U60.match _tag _t λ_tag_1(λ_x (_x λ_x 0))))
Book.A = 0
Book.A.bad = λ_P λ_new ((_new 1) 0)

2
bootstrap.js vendored
View File

@ -28,7 +28,7 @@ fs.readdirSync(bookDir).forEach(file => {
});
// Loads prelude
var prelude = fs.readFileSync("./book/Kind.Book.to_hvm.prelude.kind2", "utf8");
var prelude = fs.readFileSync("./book/Kind.Book.to_hvm.prelude.kind2", "utf8").trim();
const lines = prelude.split("\n");
lines.shift();
lines.pop();

View File

@ -355,6 +355,7 @@
(Context.show.ann (Ann val typ) dep) = (Join ["{" (Show (Normal 0 val dep) dep) ": " (Show (Normal 0 typ dep) dep) "}"])
(Context.show.ann term dep) = (Show (Normal 0 term dep) dep)
//(Context.show.ann val dep) = (Join ["{" (Show (Normal 0 val dep) dep) ": " (Show (Normal 0 (Infer val dep) dep) dep) "}"])
// Compilation
// -----------
@ -419,8 +420,8 @@ Compile.primitives = [
(Normalizer (Ref nam val)) = (Normalizer val)
(Normalizer (Ann val typ)) = (Normalizer val)
//(Normalizer val) = (Compile val)
(Normalizer val) = (Str.view (Compile val))
(Normalizer val) = (Compile val)
//(Normalizer val) = (Str.view (Compile val))
(Checker (Ref nam val)) = (Checker val)
(Checker (Ann val typ)) = (Checker.report (Check val typ 0))

174
kind2.ts
View File

@ -1,126 +1,8 @@
//// TODO
//Kind.load
//: ∀(name: String)
//Kind.Book
//= λname
//(Kind.load.name #5 name (String.Map.new Kind.Term))
//// Gets the source file of a definition
//Kind.load.file_of
//: ∀(name: String)
//String
//= λname
//(String.concat name ".kind2")
//// Loads a file into a new book
//Kind.load.file
//: ∀(file: String)
//Kind.Book
//= λfile
//(HVM.load Kind.Book file λdata
//(Kind.Book.parse data))
//// Loads a name into a book
//Kind.load.name
//: ∀(lims: #U60)
//∀(name: String)
//∀(book: Kind.Book)
//Kind.Book
//= λlims
//(HVM.log #U60 ∀(name:String)∀(book:Kind.Book)Kind.Book lims
//#match lims = lims {
//#0: λname λbook book
//#+: λname λbook
//(HVM.print Kind.Book (String.concat "LOAD:" name)
//// Checks if name is already on book
//let P = λx (Kind.Book)
//let new = λhas λbook
//// If it is, do nothing; otherwise, define it
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let true = λbook
//(HVM.print Kind.Book (String.concat (String.concat "OLD!:" name) (String.concat " -- " (Kind.keys book))) book)
//let false = λbook
//(HVM.print Kind.Book (String.concat (String.concat "NEW!:" name) (String.concat " -- " (Kind.keys book)))
//let file = (Kind.load.file (Kind.load.file_of name))
//let defs = (String.Map.to_list Kind.Term file)
//let bok1 = (Kind.load.define defs book)
//let file = (Kind.load.file (Kind.load.file_of name))
//let refs = (Kind.Book.get_refs file)
//let bok2 = (HVM.print ?a (String.concat "REC!:" (Kind.keys bok1)) (Kind.load.name.many lims-1 refs bok1))
//bok2)
////(HVM.print.many Kind.Book refs book)
//((~has P true false) book)
//(~(String.Map.has.linear Kind.Term name book) P new))
//}: ∀(name: String) ∀(book: Kind.Book) Kind.Book)
//// Loads many names into a book
//Kind.load.name.many
//: ∀(lims: #U60)
//∀(list: (List String))
//∀(book: Kind.Book)
//Kind.Book
//= λlims λlist λbook
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let cons = λhead λtail λbook
////(HVM.print Kind.Book
////(String.concat "DEP:"
////(String.concat head
////(String.concat " BOOK:"
////(Kind.Book.show book))))
//let bok2 = (Kind.load.name lims head book)
//(Kind.load.name.many lims tail bok2)
//let nil = λbook book
//((~list P cons nil) book)
//// Defines a term and loads its dependencies
////Kind.load.define
////: ∀(name: String)
////∀(term: Kind.Term)
////∀(book: Kind.Book)
////Kind.Book
////= λname λterm λbook
////let book = (String.Map.set Kind.Term name term book)
////let refs = (Kind.Term.get_refs term)
////let book = (Kind.load.name.many refs book)
////book
//// Defines many terms
//Kind.load.define
//: ∀(defs: (List (Pair String Kind.Term)))
//∀(book: Kind.Book)
//Kind.Book
//= λdefs λbook
//// If defs list isn't empty...
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let cons = λdefs.head λdefs.tail λbook
//// Gets the def name/term
//let P = λx (Kind.Book)
//let new = λname λterm
//// Writes it to the book
//let bok2 = (String.Map.set Kind.Term name term book)
//(HVM.print Kind.Book (String.concat "DEF!:" name)
//// Recurses
//(Kind.load.define defs.tail bok2))
//(~defs.head P new)
//// If defs list is empty, return the book
//let nil = λbook book
//((~defs P cons nil) book)
//Kind.keys
//: ∀(book: Kind.Book)
//String
//= λbook
//let defs = (String.Map.to_list Kind.Term book)
//let defs = (List.app (Pair String Kind.Term) String (Pair.fst String Kind.Term) defs)
//(String.join defs)
import { execSync } from 'child_process';
import * as fs from 'fs';
type Book = {[name:string]: string};
export function run(expr: string): string {
var command = `hvm1 run -t 1 -c -f bootstrap.hvm1 '${expr}'`;
try {
@ -135,51 +17,29 @@ export function str(result: string): string {
return result.slice(1,-1).trim();
}
export function get_refs(code: string): string {
return run(`(Strs.view ((Book.Kind.Book.get_refs) ((Book.Kind.Book.parse) (Str \`${code}\`))))`).trim();
export function get_refs(code: string): [string] {
return JSON.parse(run(`(Strs.view ((Book.Kind.Book.get_refs) ((Book.Kind.Book.parse) (Str \`${code}\`))))`).trim());
}
export function to_hvm(code: string): string {
return str(run(`(Str.view ((Book.Kind.Book.to_hvm) ((Book.Kind.Book.parse) (Str \`${code}\`))))`).trim());
}
//// Loads a name into a book
//Kind.load.name
//: ∀(lims: #U60)
//∀(name: String)
//∀(book: Kind.Book)
//Kind.Book
//= λlims
//(HVM.log #U60 ∀(name:String)∀(book:Kind.Book)Kind.Book lims
//#match lims = lims {
//#0: λname λbook book
//#+: λname λbook
//(HVM.print Kind.Book (String.concat "LOAD:" name)
//// Checks if name is already on book
//let P = λx (Kind.Book)
//let new = λhas λbook
//// If it is, do nothing; otherwise, define it
//let P = λx ∀(book: Kind.Book) (Kind.Book)
//let true = λbook
//(HVM.print Kind.Book (String.concat (String.concat "OLD!:" name) (String.concat " -- " (Kind.keys book))) book)
//let false = λbook
//(HVM.print Kind.Book (String.concat (String.concat "NEW!:" name) (String.concat " -- " (Kind.keys book)))
//let file = (Kind.load.file (Kind.load.file_of name))
//let defs = (String.Map.to_list Kind.Term file)
//let bok1 = (Kind.load.define defs book)
//let file = (Kind.load.file (Kind.load.file_of name))
//let refs = (Kind.Book.get_refs file)
//let bok2 = (HVM.print ?a (String.concat "REC!:" (Kind.keys bok1)) (Kind.load.name.many lims-1 refs bok1))
//bok2)
////(HVM.print.many Kind.Book refs book)
//((~has P true false) book)
//(~(String.Map.has.linear Kind.Term name book) P new))
//}: ∀(name: String) ∀(book: Kind.Book) Kind.Book)
export function load_file(file: string): string {
return fs.readFileSync("./book/"+file, "utf8");
}
export function load_name(
export function load(name: string, book: Book = {}): Book {
console.log("loading", name);
book[name] = load_file(name + ".kind2");
var refs = get_refs(book[name]);
for (var ref of refs) {
if (!book[ref]) {
load(ref, book);
}
}
return book;
}
console.log(get_refs(load("Bool")));
console.log(load("Bool", {}));