├── .gitattributes ├── .gitignore ├── LICENSE ├── Lisp.kind2 └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | **/*.kind2 linguist-language=Kind(type:programming) 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.check.hvm 2 | tmp/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 noge-labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Lisp.kind2: -------------------------------------------------------------------------------- 1 | #derive[match] 2 | type Lisp.Term { 3 | list (values: List Lisp.Term) 4 | atom (name: String) 5 | num (value: U60) 6 | } 7 | 8 | Lisp.Term.Atom.to_string (term : Lisp.Term) : Maybe String 9 | Lisp.Term.Atom.to_string (Lisp.Term.atom name) = Maybe.some name 10 | Lisp.Term.Atom.to_string _term = Maybe.none 11 | 12 | // Env 13 | 14 | record Lisp.Env { 15 | vars: Map Lisp.Term 16 | } 17 | 18 | Lisp.Env.empty : Lisp.Env 19 | Lisp.Env.empty = Lisp.Env.new Map.new 20 | 21 | // Parser Implementation 22 | 23 | Lisp.parser : Parser Lisp.Env Lisp.Term 24 | Lisp.parser = do Parser { 25 | Parser.skip_whitespace 26 | Lisp.parser.term 27 | } 28 | 29 | Lisp.parser.term : Parser Lisp.Env Lisp.Term 30 | Lisp.parser.term = 31 | let parsers = [ 32 | Lisp.parser.list, 33 | Lisp.parser.atom, 34 | Lisp.parser.num 35 | ] 36 | 37 | Parser.first_of parsers 38 | 39 | Lisp.parser.list : Parser Lisp.Env Lisp.Term 40 | Lisp.parser.list = do Parser { 41 | Parser.char '(' 42 | Parser.skip_whitespace 43 | ask values = Parser.sep_by Parser.whitespace Lisp.parser.term 44 | Parser.skip_whitespace 45 | Parser.char ')' 46 | 47 | return Lisp.Term.list values 48 | } 49 | 50 | Lisp.parser.atom : Parser Lisp.Env Lisp.Term 51 | Lisp.parser.atom = do Parser { 52 | ask name = Lisp.parser.name 53 | return Lisp.Term.atom name 54 | } 55 | 56 | Lisp.parser.name : Parser Lisp.Env String 57 | Lisp.parser.name = do Parser { 58 | ask name = Parser.take_while1 (c => Lisp.parser.valid_char c) 59 | return name 60 | } 61 | 62 | Lisp.parser.valid_char (char: Char) : Bool 63 | Lisp.parser.valid_char c = 64 | let operators = ['<', '>', '=', '+', '-', '*', '/'] 65 | let is_operator = (x: Char) => List.any operators ((y: Char) => Char.equal x y) 66 | 67 | (Bool.if (Bool.or (Char.is_alpha c) (is_operator c)) Bool.true Bool.false) 68 | 69 | Lisp.parser.num : Parser Lisp.Env Lisp.Term 70 | Lisp.parser.num = do Parser { 71 | ask value = Parser.u60_decimal 72 | return Lisp.Term.num value 73 | } 74 | 75 | // Transform 76 | 77 | record Lisp.Hir.Lambda { 78 | args: List String 79 | body: Lisp.Hir 80 | } 81 | 82 | record Lisp.Hir.Define { 83 | defn: Pair String Lisp.Hir 84 | body: Lisp.Hir 85 | } 86 | 87 | record Lisp.Hir.If { 88 | cond: Lisp.Hir 89 | then: Lisp.Hir 90 | else: Lisp.Hir 91 | } 92 | 93 | record Lisp.Hir.Call { 94 | func: String 95 | args: List Lisp.Hir 96 | } 97 | 98 | type Lisp.Hir { 99 | lambda (lambda: Lisp.Hir.Lambda) 100 | define (define: Lisp.Hir.Define) 101 | ifstmt (ifstmt: Lisp.Hir.If) 102 | call (call: Lisp.Hir.Call) 103 | list (values: List Lisp.Hir) 104 | atom (value: String) 105 | bool (value: Bool) 106 | num (value: U60) 107 | } 108 | 109 | // Transform Term 110 | 111 | Lisp.Hir.from_term (term: Lisp.Term) : Maybe Lisp.Hir 112 | Lisp.Hir.from_term (Lisp.Term.num x) = do Maybe { 113 | return (Lisp.Hir.num x) 114 | } 115 | 116 | Lisp.Hir.from_term (Lisp.Term.atom x) = 117 | (Bool.if (String.equal x "#t") (Maybe.some (Lisp.Hir.bool Bool.true)) 118 | (Bool.if (String.equal x "#f") (Maybe.some (Lisp.Hir.bool Bool.false)) 119 | (Maybe.some (Lisp.Hir.atom x)))) 120 | 121 | Lisp.Hir.from_term (Lisp.Term.list terms) = do Maybe { 122 | Lisp.Hir.from_terms terms 123 | } 124 | 125 | // Transform Terms 126 | 127 | Lisp.Hir.from_terms (terms: List Lisp.Term) : Maybe Lisp.Hir 128 | Lisp.Hir.from_terms (List.cons (Lisp.Term.atom atom) tail) = do Maybe { 129 | Lisp.Hir.from_symbol_list atom tail 130 | } 131 | 132 | Lisp.Hir.from_terms (List.cons head List.nil) = do Maybe { 133 | Lisp.Hir.from_term head 134 | } 135 | 136 | Lisp.Hir.from_terms (List.cons head tail) = do Maybe { 137 | let list = List.cons Lisp.Term head tail 138 | let list = Lisp.Hir.from_term (Lisp.Term.list list) 139 | list 140 | } 141 | 142 | Lisp.Hir.from_terms (List.nil) = do Maybe { 143 | return (Lisp.Hir.list []) 144 | } 145 | 146 | Lisp.Hir.from_symbol_list (symbol: String) (terms: List Lisp.Term) : Maybe Lisp.Hir 147 | Lisp.Hir.from_symbol_list identifier terms = 148 | (Bool.if (String.equal identifier "define") (Lisp.Hir.from_terms.try_define terms) 149 | (Bool.if (String.equal identifier "lambda") (Lisp.Hir.from_terms.try_lambda terms) 150 | (Bool.if (String.equal identifier "list") (Lisp.Hir.from_terms.try_list terms) 151 | (Bool.if (String.equal identifier "if") (Lisp.Hir.from_terms.try_ifstmt terms) 152 | (Lisp.Hir.from_terms.try_called identifier terms))))) 153 | 154 | // Transform Lambda 155 | 156 | Lisp.Hir.from_terms.try_lambda (terms: List Lisp.Term) : Maybe Lisp.Hir 157 | Lisp.Hir.from_terms.try_lambda (List.nil) = Maybe.none 158 | Lisp.Hir.from_terms.try_lambda (List.cons Lisp.Term head tail) = do Maybe { 159 | match Lisp.Term head { 160 | list values => do Maybe { 161 | ask body = Lisp.Hir.from_terms tail 162 | ask args = Lisp.Hir.from_terms.try_lambda.args head 163 | let func = Lisp.Hir.Lambda.new args body 164 | 165 | return (Lisp.Hir.lambda func) 166 | } 167 | 168 | atom name => Maybe.none 169 | num value => Maybe.none 170 | } 171 | } 172 | 173 | Lisp.Hir.from_terms.try_lambda (List.cons (List.nil) tail) = do Maybe { 174 | ask body = Lisp.Hir.from_terms tail 175 | 176 | return (Lisp.Hir.lambda (Lisp.Hir.Lambda.new [] body)) 177 | } 178 | 179 | // Transform Lambda args 180 | 181 | Lisp.Hir.from_terms.try_lambda.args (args: Lisp.Term) : Maybe (List String) 182 | Lisp.Hir.from_terms.try_lambda.args (Lisp.Term.list (List.nil)) = do Maybe { 183 | return List.nil 184 | } 185 | 186 | Lisp.Hir.from_terms.try_lambda.args (Lisp.Term.list (List.cons arg args)) = 187 | match Lisp.Term arg { 188 | list values => Lisp.Hir.from_terms.try_lambda.args (Lisp.Term.list args) 189 | num value => Lisp.Hir.from_terms.try_lambda.args (Lisp.Term.list args) 190 | atom name => do Maybe { 191 | let args = Lisp.Term.list args 192 | ask args = Lisp.Hir.from_terms.try_lambda.args args 193 | 194 | return List.cons name args 195 | } 196 | } 197 | 198 | 199 | // Transform Define 200 | 201 | Lisp.Hir.from_terms.try_define (terms: List Lisp.Term) : Maybe Lisp.Hir 202 | Lisp.Hir.from_terms.try_define (List.cons Lisp.Term define body) = 203 | match Lisp.Term define { 204 | list values => 205 | match List values { 206 | nil => Maybe.none 207 | cons head tail => do Maybe { 208 | ask name = Lisp.Term.Atom.to_string head 209 | ask value = List.at tail (U60.to_nat 0) 210 | ask value = Lisp.Hir.from_term value 211 | ask body = Lisp.Hir.from_terms body 212 | 213 | return Lisp.Hir.define (Lisp.Hir.Define.new (Pair.new name value) body) 214 | } 215 | } 216 | atom => Maybe.none 217 | num => Maybe.none 218 | } 219 | 220 | // Transform If Statement 221 | 222 | Lisp.Hir.from_terms.try_ifstmt (terms: List Lisp.Term) : Maybe Lisp.Hir 223 | Lisp.Hir.from_terms.try_ifstmt (List.cons cond rest) = do Maybe { 224 | ask cond = Lisp.Hir.from_term cond 225 | ask then = List.at rest (U60.to_nat 0) 226 | ask then = Lisp.Hir.from_term then 227 | ask else = List.at rest (U60.to_nat 1) 228 | ask else = Lisp.Hir.from_term else 229 | 230 | return Lisp.Hir.ifstmt (Lisp.Hir.If.new cond then else) 231 | } 232 | 233 | Lisp.Hir.from_terms.try_list (terms: List Lisp.Term) : Maybe Lisp.Hir 234 | Lisp.Hir.from_terms.try_list (List.cons head tail) = do Maybe { 235 | let list = List.cons Lisp.Term head tail 236 | let list = List.map list (x => Lisp.Hir.from_term x) 237 | ask list = Maybe.sequence list 238 | 239 | return Lisp.Hir.list list 240 | } 241 | 242 | // Transform Call Function 243 | 244 | Lisp.Hir.from_terms.try_called (term: String) (terms: List Lisp.Term) : Maybe Lisp.Hir 245 | Lisp.Hir.from_terms.try_called func (List.cons head tail) = do Maybe { 246 | let args = List.cons Lisp.Term head tail 247 | let args = List.map args (arg => Lisp.Hir.from_term arg) 248 | ask args = Maybe.sequence args 249 | 250 | return Lisp.Hir.call (Lisp.Hir.Call.new func args) 251 | } 252 | 253 | Lisp.Hir.from_terms.try_called func List.nil = do Maybe { 254 | return Lisp.Hir.atom func 255 | } 256 | 257 | // Environment 258 | 259 | Lisp.Entry: Type 260 | Lisp.Entry = Pair String Lisp.Value 261 | Lisp.Entry.compare (key: String) (e: Lisp.Entry) { 262 | (String.equal (Pair.fst e) key) 263 | } 264 | 265 | Lisp.Value.Env: Type 266 | Lisp.Value.Env = List Lisp.Entry 267 | 268 | Lisp.Value.Env.new: Lisp.Value.Env 269 | Lisp.Value.Env.new = [] 270 | 271 | Lisp.Value.Env.empty : Lisp.Value.Env 272 | Lisp.Value.Env.empty = Lisp.Value.Env.new 273 | 274 | Lisp.Value.Env.take (env: Lisp.Value.Env) (name: String): Pair Lisp.Value.Env (Maybe Lisp.Value) 275 | Lisp.Value.Env.take env key = 276 | let val = (Maybe.map (x => (Pair.snd x)) (List.head (List.filter env (e => (Lisp.Entry.compare key e))))) 277 | Pair.new env val 278 | 279 | Lisp.Value.Env.subst (env: Lisp.Value.Env) (name: String) (value: Lisp.Value): Lisp.Value.Env 280 | Lisp.Value.Env.subst env name value = 281 | let entry = (List.head (List.filter env (e => (Lisp.Entry.compare name e)))) 282 | match Maybe entry { 283 | some => List.map env (entry => (Bool.if (Lisp.Entry.compare name entry) (Pair.new name value) entry)) 284 | none => List.cons (Pair.new name value) env 285 | } 286 | 287 | // Evaluate 288 | 289 | record Lisp.Value.Proc { 290 | params: List String 291 | body: Lisp.Hir 292 | ctx: Lisp.Value.Env 293 | } 294 | 295 | record Lisp.Value.Call { 296 | func: String 297 | args: List Lisp.Value 298 | } 299 | 300 | record Lisp.Value.Prim { 301 | fun: (Lisp.Value.Env -> List Lisp.Value -> Maybe Lisp.Value) 302 | } 303 | 304 | #derive[match] 305 | type Lisp.Value { 306 | proc (proc: Lisp.Value.Proc) 307 | prim (prim: Lisp.Value.Prim) 308 | call (call: Lisp.Value.Call) 309 | list (values: List Lisp.Value) 310 | bool (value: Bool) 311 | num (value: U60) 312 | atom (value: String) 313 | } 314 | 315 | Lisp.Evaluate.hir (env: Lisp.Value.Env) (term: Lisp.Hir) : Maybe Lisp.Value 316 | Lisp.Evaluate.hir env (Lisp.Hir.list values) = do Maybe { 317 | let values = List.map values (value => Lisp.Evaluate.hir env value) 318 | ask values = Maybe.sequence values 319 | 320 | return (Lisp.Value.list values) 321 | } 322 | 323 | Lisp.Evaluate.hir env (Lisp.Hir.atom value) = do Maybe { 324 | let take_value = Lisp.Value.Env.take env value 325 | let snd_value = Pair.snd take_value 326 | 327 | return match Maybe snd_value { 328 | some value => value 329 | none => (Lisp.Value.atom value) 330 | } 331 | } 332 | 333 | Lisp.Evaluate.hir env (Lisp.Hir.bool value) = do Maybe { 334 | return Lisp.Value.bool value 335 | } 336 | 337 | Lisp.Evaluate.hir env (Lisp.Hir.num value) = do Maybe { 338 | return Lisp.Value.num value 339 | } 340 | 341 | Lisp.Evaluate.hir env (Lisp.Hir.define define) = do Maybe { 342 | Lisp.Evaluate.define env define 343 | } 344 | 345 | Lisp.Evaluate.hir env (Lisp.Hir.lambda lambda) = do Maybe { 346 | Lisp.Evaluate.lambda env lambda 347 | } 348 | 349 | Lisp.Evaluate.hir env (Lisp.Hir.ifstmt ifstmt) = do Maybe { 350 | Lisp.Evaluate.ifstmt env ifstmt 351 | } 352 | 353 | Lisp.Evaluate.hir env (Lisp.Hir.call call) = do Maybe { 354 | Lisp.Evaluate.call env call 355 | } 356 | 357 | Lisp.Evaluate.define (env: Lisp.Value.Env) (term: Lisp.Hir.Define) : Maybe Lisp.Value 358 | Lisp.Evaluate.define env (Lisp.Hir.Define.new (Pair.new String Lisp.Hir fst snd) body) = do Maybe { 359 | ask value = Lisp.Evaluate.hir env snd 360 | let env = Lisp.Value.Env.subst env fst value 361 | 362 | Lisp.Evaluate.hir env body 363 | } 364 | 365 | Lisp.Evaluate.lambda (env: Lisp.Value.Env) (term: Lisp.Hir.Lambda) : Maybe Lisp.Value 366 | Lisp.Evaluate.lambda env (Lisp.Hir.Lambda.new params body) = do Maybe { 367 | return Lisp.Value.proc (Lisp.Value.Proc.new params body env) 368 | } 369 | 370 | Lisp.Evaluate.ifstmt (env: Lisp.Value.Env) (term: Lisp.Hir.If) : Maybe Lisp.Value 371 | Lisp.Evaluate.ifstmt env (Lisp.Hir.If.new cond then else) = do Maybe { 372 | ask cond = Lisp.Evaluate.hir env cond 373 | Lisp.Evaluate.ifstmt.branch env cond then else 374 | } 375 | 376 | Lisp.Evaluate.ifstmt.branch (env: Lisp.Value.Env) (cond: Lisp.Value) (then: Lisp.Hir) (else: Lisp.Hir) : Maybe Lisp.Value 377 | Lisp.Evaluate.ifstmt.branch env (Lisp.Value.bool Bool.true) then _ = Lisp.Evaluate.hir env then 378 | Lisp.Evaluate.ifstmt.branch env (Lisp.Value.bool Bool.false) _ else = Lisp.Evaluate.hir env else 379 | Lisp.Evaluate.ifstmt.branch env _ _ else = Lisp.Evaluate.hir env else 380 | 381 | Lisp.Evaluate.call (env: Lisp.Value.Env) (term: Lisp.Hir.Call) : Maybe Lisp.Value 382 | Lisp.Evaluate.call env (Lisp.Hir.Call.new func args) = do Maybe { 383 | ask eval = Lisp.Evaluate.hir env (Lisp.Hir.atom func) 384 | 385 | let args = List.map args (arg => Lisp.Evaluate.hir env arg) 386 | ask args = Maybe.sequence args 387 | 388 | match Lisp.Value eval { 389 | proc proc => Lisp.Evaluate.call.apply_proc env proc args 390 | prim prim => Lisp.Evaluate.call.apply_prim env prim args 391 | call call => Maybe.some (Lisp.Value.call (Lisp.Value.Call.new func args)) 392 | list values => Maybe.some (Lisp.Value.call (Lisp.Value.Call.new func args)) 393 | bool value => Maybe.some (Lisp.Value.call (Lisp.Value.Call.new func args)) 394 | num value => Maybe.some (Lisp.Value.call (Lisp.Value.Call.new func args)) 395 | atom value => Maybe.some (Lisp.Value.call (Lisp.Value.Call.new func args)) 396 | } 397 | } 398 | 399 | Lisp.Evaluate.call.apply_proc (env: Lisp.Value.Env) (func: Lisp.Value.Proc) (args: List Lisp.Value) : Maybe Lisp.Value 400 | Lisp.Evaluate.call.apply_proc env (Lisp.Value.Proc.new params body ctx) args = do Maybe { 401 | let env = Lisp.Evaluate.call.apply_proc.args ctx params args 402 | Lisp.Evaluate.hir env body 403 | } 404 | 405 | Lisp.Evaluate.call.apply_proc.args (env: Lisp.Value.Env) (params: List String) (args: List Lisp.Value) : Lisp.Value.Env 406 | Lisp.Evaluate.call.apply_proc.args env (List.nil) (List.nil) = env 407 | Lisp.Evaluate.call.apply_proc.args env (List.cons String param params) (List.cons Lisp.Value arg args) = 408 | let env = Lisp.Value.Env.subst env param arg 409 | Lisp.Evaluate.call.apply_proc.args env params args 410 | 411 | Lisp.Evaluate.call.apply_prim (env: Lisp.Value.Env) (func: Lisp.Value.Prim) (args: List Lisp.Value) : Maybe Lisp.Value 412 | Lisp.Evaluate.call.apply_prim env (Lisp.Value.Prim.new fun) args = fun env args 413 | 414 | Lisp.Prim.Definition.required_args (args: List Lisp.Value) (size: U60) : Maybe Unit 415 | Lisp.Prim.Definition.required_args args size = 416 | (Bool.if (U60.equal (Nat.to_u60 (List.length args)) size) 417 | (Maybe.some Unit.new) 418 | (Maybe.none)) 419 | 420 | // Default fn tail 421 | 422 | Lisp.Prim.Definition.tail (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 423 | Lisp.Prim.Definition.tail env args = do Maybe { 424 | Lisp.Prim.Definition.required_args args 1 425 | 426 | ask head = List.head Lisp.Value args 427 | Lisp.Prim.Definition.tail_aux head 428 | } 429 | 430 | Lisp.Prim.Definition.tail_aux (args: Lisp.Value) : Maybe Lisp.Value 431 | Lisp.Prim.Definition.tail_aux (Lisp.Value.list (List.cons head tail)) = Maybe.some (Lisp.Value.list tail) 432 | Lisp.Prim.Definition.tail_aux _ = Maybe.some (Lisp.Value.list []) 433 | 434 | // Default fn head 435 | 436 | Lisp.Prim.Definition.head (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 437 | Lisp.Prim.Definition.head env args = do Maybe { 438 | Lisp.Prim.Definition.required_args args 1 439 | 440 | ask head = List.head Lisp.Value args 441 | Lisp.Prim.Definition.head_aux head 442 | } 443 | 444 | Lisp.Prim.Definition.head_aux (args: Lisp.Value) : Maybe Lisp.Value 445 | Lisp.Prim.Definition.head_aux (Lisp.Value.list (List.cons head tail)) = Maybe.some head 446 | Lisp.Prim.Definition.head_aux _ = Maybe.some (Lisp.Value.list []) 447 | 448 | // Default fn cons 449 | 450 | Lisp.Prim.Definition.cons (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 451 | Lisp.Prim.Definition.cons env args = do Maybe { 452 | Lisp.Prim.Definition.required_args args 2 453 | 454 | ask fst = List.at Lisp.Value args (U60.to_nat 0) 455 | ask snd = List.at Lisp.Value args (U60.to_nat 1) 456 | 457 | Lisp.Prim.Definition.cons_aux fst snd 458 | } 459 | 460 | Lisp.Prim.Definition.cons_aux (fst: Lisp.Value) (snd: Lisp.Value) : Maybe Lisp.Value 461 | Lisp.Prim.Definition.cons_aux fst (Lisp.Value.list (List.cons head tail)) = Maybe.some (Lisp.Value.list (List.cons fst (List.cons Lisp.Value head tail))) 462 | Lisp.Prim.Definition.cons_aux fst snd = Maybe.some (Lisp.Value.list (List.cons fst [snd])) 463 | 464 | // Default is-nil 465 | 466 | Lisp.Prim.Definition.is_nil (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 467 | Lisp.Prim.Definition.is_nil env args = do Maybe { 468 | Lisp.Prim.Definition.required_args args 1 469 | 470 | ask head = List.head Lisp.Value args 471 | 472 | Lisp.Prim.Definition.is_nil_aux head 473 | } 474 | 475 | Lisp.Prim.Definition.is_nil_aux (args: Lisp.Value) : Maybe Lisp.Value 476 | Lisp.Prim.Definition.is_nil_aux (Lisp.Value.list (List.nil)) = Maybe.some (Lisp.Value.bool Bool.true) 477 | Lisp.Prim.Definition.is_nil_aux _ = Maybe.some (Lisp.Value.list []) 478 | 479 | // Default is-cons 480 | 481 | Lisp.Prim.Definition.is_cons (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 482 | Lisp.Prim.Definition.is_cons env args = do Maybe { 483 | Lisp.Prim.Definition.required_args args 1 484 | 485 | ask head = List.head Lisp.Value args 486 | 487 | Lisp.Prim.Definition.is_cons_aux head 488 | } 489 | 490 | Lisp.Prim.Definition.is_cons_aux (args: Lisp.Value) : Maybe Lisp.Value 491 | Lisp.Prim.Definition.is_cons_aux (Lisp.Value.list (List.cons head tail)) = Maybe.some (Lisp.Value.bool Bool.true) 492 | Lisp.Prim.Definition.is_cons_aux _ = Maybe.some (Lisp.Value.list []) 493 | 494 | // Default fn reverse 495 | 496 | Lisp.Prim.Definition.reverse (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 497 | Lisp.Prim.Definition.reverse env args = do Maybe { 498 | Lisp.Prim.Definition.required_args args 1 499 | 500 | ask head = List.head Lisp.Value args 501 | 502 | Lisp.Prim.Definition.reverse_aux head 503 | } 504 | 505 | Lisp.Prim.Definition.reverse_aux (args: Lisp.Value) : Maybe Lisp.Value 506 | Lisp.Prim.Definition.reverse_aux (Lisp.Value.list (List.cons head tail)) = Maybe.some (Lisp.Value.list (List.reverse (List.cons Lisp.Value head tail))) 507 | Lisp.Prim.Definition.reverse_aux _ = Maybe.some (Lisp.Value.list []) 508 | 509 | // Default Comparations 510 | 511 | Lisp.Prim.Definition.comparation (operation: U60 -> U60 -> Bool) (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 512 | Lisp.Prim.Definition.comparation operation env args = do Maybe { 513 | Lisp.Prim.Definition.required_args args 2 514 | 515 | ask fst = List.at Lisp.Value args (U60.to_nat 0) 516 | ask snd = List.at Lisp.Value args (U60.to_nat 1) 517 | 518 | Lisp.Prim.Definition.comparation_aux operation fst snd 519 | } 520 | 521 | Lisp.Prim.Definition.comparation_aux (operation: U60 -> U60 -> Bool) (fst: Lisp.Value) (snd: Lisp.Value) : Maybe Lisp.Value 522 | Lisp.Prim.Definition.comparation_aux operation (Lisp.Value.num x) (Lisp.Value.num y) = Maybe.some (Lisp.Value.bool (operation x y)) 523 | Lisp.Prim.Definition.comparation_aux _ _ _ = Maybe.some (Lisp.Value.bool (Bool.false)) 524 | 525 | // Default operators 526 | 527 | Lisp.Prim.Definition.operator (start: U60) (operation: U60 -> U60 -> U60) (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 528 | Lisp.Prim.Definition.operator start operation env args = do Maybe { 529 | ask args = Lisp.Prim.Definition.operator.args args 530 | let fold = List.foldl U60 U60 start ((curr: U60) => (acc: U60) => operation acc curr) args 531 | 532 | return Lisp.Value.num fold 533 | } 534 | 535 | Lisp.Prim.Definition.operator.args (args: List Lisp.Value) : Maybe (List U60) 536 | Lisp.Prim.Definition.operator.args args = do Maybe { 537 | let args = List.map args (arg => Lisp.Prim.Definition.operator.arg arg) 538 | Maybe.sequence args 539 | } 540 | 541 | Lisp.Prim.Definition.operator.arg (arg: Lisp.Value) : Maybe U60 542 | Lisp.Prim.Definition.operator.arg (Lisp.Value.num num) = Maybe.some num 543 | Lisp.Prim.Definition.operator.arg _ = Maybe.none 544 | 545 | // Default operator + 546 | 547 | Lisp.Prim.Definition.operator.plus (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 548 | Lisp.Prim.Definition.operator.plus env args = Lisp.Prim.Definition.operator 0 ((x: U60) => (y: U60) => (+ x y)) env args 549 | 550 | // Default operator - 551 | 552 | Lisp.Prim.Definition.operator.minus (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 553 | Lisp.Prim.Definition.operator.minus env args = Lisp.Prim.Definition.operator 0 ((x: U60) => (y: U60) => (- x y)) env args 554 | 555 | // Default operator * 556 | 557 | Lisp.Prim.Definition.operator.mult (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 558 | Lisp.Prim.Definition.operator.mult env args = Lisp.Prim.Definition.operator 1 ((x: U60) => (y: U60) => (* x y)) env args 559 | 560 | // Default operator < 561 | 562 | Lisp.Prim.Definition.operator.lt (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 563 | Lisp.Prim.Definition.operator.lt env args = Lisp.Prim.Definition.comparation ((x: U60) => (y: U60) => (U60.less_than x y)) env args 564 | 565 | // Default operator <= 566 | 567 | Lisp.Prim.Definition.operator.le (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 568 | Lisp.Prim.Definition.operator.le env args = Lisp.Prim.Definition.comparation ((x: U60) => (y: U60) => (U60.less_equal x y)) env args 569 | 570 | // Default operator > 571 | 572 | Lisp.Prim.Definition.operator.gt (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 573 | Lisp.Prim.Definition.operator.gt env args = Lisp.Prim.Definition.comparation ((x: U60) => (y: U60) => (U60.greater_than x y)) env args 574 | 575 | // Default operator >= 576 | 577 | Lisp.Prim.Definition.operator.ge (env: Lisp.Value.Env) (args: List Lisp.Value) : Maybe Lisp.Value 578 | Lisp.Prim.Definition.operator.ge env args = Lisp.Prim.Definition.comparation ((x: U60) => (y: U60) => (U60.greater_equal x y)) env args 579 | 580 | // Default environment 581 | 582 | Lisp.Prim.new (fun: (Lisp.Value.Env -> List Lisp.Value -> Maybe Lisp.Value)) : Lisp.Value 583 | Lisp.Prim.new fun = Lisp.Value.prim (Lisp.Value.Prim.new fun) 584 | 585 | Lisp.default_env (env : Lisp.Value.Env) : Lisp.Value.Env 586 | Lisp.default_env env = 587 | let env = Lisp.Value.Env.subst env "reverse" (Lisp.Prim.new ( 588 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.reverse env args 589 | )) 590 | let env = Lisp.Value.Env.subst env "is-cons" (Lisp.Prim.new ( 591 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.is_cons env args 592 | )) 593 | let env = Lisp.Value.Env.subst env "is-nil" (Lisp.Prim.new ( 594 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.is_nil env args 595 | )) 596 | let env = Lisp.Value.Env.subst env "cons" (Lisp.Prim.new ( 597 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.cons env args 598 | )) 599 | let env = Lisp.Value.Env.subst env "head" (Lisp.Prim.new ( 600 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.head env args 601 | )) 602 | let env = Lisp.Value.Env.subst env "tail" (Lisp.Prim.new ( 603 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.tail env args 604 | )) 605 | let env = Lisp.Value.Env.subst env "+" (Lisp.Prim.new ( 606 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.plus env args 607 | )) 608 | let env = Lisp.Value.Env.subst env "-" (Lisp.Prim.new ( 609 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.minus env args 610 | )) 611 | let env = Lisp.Value.Env.subst env "*" (Lisp.Prim.new ( 612 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.mult env args 613 | )) 614 | let env = Lisp.Value.Env.subst env "<" (Lisp.Prim.new ( 615 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.lt env args 616 | )) 617 | let env = Lisp.Value.Env.subst env "<=" (Lisp.Prim.new ( 618 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.le env args 619 | )) 620 | let env = Lisp.Value.Env.subst env ">" (Lisp.Prim.new ( 621 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.gt env args 622 | )) 623 | let env = Lisp.Value.Env.subst env ">=" (Lisp.Prim.new ( 624 | (env: Lisp.Value.Env) => (args: List Lisp.Value) => Lisp.Prim.Definition.operator.ge env args 625 | )) 626 | env 627 | 628 | Main : _ { 629 | let input = "(define (test (lambda (x) (if (>= x (* 4 8)) (* x 2) (+ x 4)))) (test (* 4 8)))" // 64 630 | let init = Parser.State.new Lisp.Env.empty input "" 0 631 | let env = Lisp.default_env Lisp.Value.Env.empty 632 | 633 | match Parser.Result r = ((Lisp.parser) init) { 634 | fail state error => Maybe.none 635 | done state result => do Maybe { 636 | ask hir = Lisp.Hir.from_term result 637 | ask res = Lisp.Evaluate.hir env hir 638 | return res 639 | } 640 | } 641 | } 642 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kind2lisp 2 | 3 | ## Usage 4 | 5 | 1. First, install [Kind2](https://github.com/HigherOrderCO/kind)  6 | 2. Clone the [Wikind](https://github.com/HigherOrderCO/Wikind) package repository 7 | 3. Move `Lisp.kind2` file to `Wikind` folder 8 | 4. Run `kind2 run Lisp.kind2` 9 | --------------------------------------------------------------------------------