aboutsummaryrefslogtreecommitdiff
path: root/src/lang/parser.clj
diff options
context:
space:
mode:
authorEduardo Julian2014-11-29 02:29:56 -0400
committerEduardo Julian2014-11-29 02:29:56 -0400
commit74f1d02a2f16da9e2ce2fb747dad07979a9db26a (patch)
treed710b3178c804a4fe5d4f8cad0903fc787e60710 /src/lang/parser.clj
parent71b63cbbb858b85dd4850c4aa174cf7ec509b11c (diff)
+ Added simple let expressions. (No destructuring of tuples/records yet)
+ Added records and simple operations on them (get, set & remove).
Diffstat (limited to '')
-rw-r--r--src/lang/parser.clj61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/lang/parser.clj b/src/lang/parser.clj
index b3cb5cbc0..2abb75cf5 100644
--- a/src/lang/parser.clj
+++ b/src/lang/parser.clj
@@ -36,6 +36,16 @@
?parts)]
(return [::tuple =parts])))
+(defparser ^:private parse-record
+ [::&lexer/record ?parts]
+ (exec [=kvs (do (assert (even? (count ?parts)))
+ (map-m #(match %
+ ([[::&lexer/tag ?label] ?value] :seq)
+ (exec [=value (apply-m parse-form (list ?value))]
+ (return [?label =value])))
+ (partition 2 ?parts)))]
+ (return [::record =kvs])))
+
(defparser ^:private parse-def
[::&lexer/list ([[::&lexer/ident "def"] ?name ?body] :seq)]
(exec [=name (apply-m parse-form (list ?name))
@@ -72,11 +82,38 @@
(partition 2 cases)))]
(return [::case =variant =branches])))
+(defparser ^:private parse-let
+ [::&lexer/list ([[::&lexer/ident "let"] [::&lexer/tuple ?bindings] ?expr] :seq)]
+ (exec [=expr (apply-m parse-form (list ?expr))
+ =bindings (do (assert (even? (count ?bindings)))
+ (map-m (fn [[destruct expr]]
+ (exec [=destruct (apply-m parse-form (list destruct))
+ =expr (apply-m parse-form (list expr))]
+ (return [::let-binding =destruct =expr])))
+ (partition 2 ?bindings)))]
+ (return [::let =bindings =expr])))
+
(defparser ^:private parse-tagged
[::&lexer/list ([[::&lexer/tag ?tag] ?data] :seq)]
(exec [=data (apply-m parse-form (list ?data))]
(return [::tagged ?tag =data])))
+(defparser ^:private parse-get
+ [::&lexer/list ([[::&lexer/ident "get@"] [::&lexer/tag ?tag] ?record] :seq)]
+ (exec [=record (apply-m parse-form (list ?record))]
+ (return [::get ?tag =record])))
+
+(defparser ^:private parse-remove
+ [::&lexer/list ([[::&lexer/ident "remove@"] [::&lexer/tag ?tag] ?record] :seq)]
+ (exec [=record (apply-m parse-form (list ?record))]
+ (return [::remove ?tag =record])))
+
+(defparser ^:private parse-set
+ [::&lexer/list ([[::&lexer/ident "set@"] [::&lexer/tag ?tag] ?value ?record] :seq)]
+ (exec [=value (apply-m parse-form (list ?value))
+ =record (apply-m parse-form (list ?record))]
+ (return [::set ?tag =value =record])))
+
(defparser ^:private parse-fn-call
[::&lexer/list ([?f & ?args] :seq)]
(exec [=f (apply-m parse-form (list ?f))
@@ -89,11 +126,16 @@
parse-float
parse-ident
parse-tuple
+ parse-record
parse-def
parse-defdata
parse-if
parse-case
+ parse-let
parse-tagged
+ parse-get
+ parse-set
+ parse-remove
parse-fn-call]))
;; [Interface]
@@ -106,22 +148,3 @@
[::&util/failure ?message]
(assert false ?message)))
-
-(comment
- ((comp parse list &lexer/lex) (slurp "src/example/test1.lang"))
-
- (&lexer/lex (slurp "src/example/test1.lang"))
- "\n(def (** base exp)\n (reduce * 1 (repeat exp base)))\n"
-
- [::list ([::ident "def"]
- [::list ([::ident "**"] [::ident "base"] [::ident "exp"])]
- [::list ([::ident "reduce"]
- [::ident "*"]
- [::int "1"]
- [::list ([::ident "repeat"]
- [::ident "exp"]
- [::ident "base"])])])]
-
- (re-find #"^([a-zA-Z!@$%^&*<>\.,/\\\|][a-zA-Z0-9!@$%^&*<>\.,/\\\|]*)" "a9")
- (re-find #"^([1-9][0-9]*)" "9")
- )