diff options
Diffstat (limited to '')
-rw-r--r-- | source/luxc/parser.lux | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/source/luxc/parser.lux b/source/luxc/parser.lux new file mode 100644 index 000000000..35ec12b17 --- /dev/null +++ b/source/luxc/parser.lux @@ -0,0 +1,72 @@ +(use ./util #as &util #refer [do return fail try-all repeat]) +(use ./lexer #as &lexer) + +;; [Utils] +(do-template [<name> <close-token> <description> <tag>] + (def (<name> parse) + (do [elems (repeat parse) + token &lexer:lex] + (case token + <close-token> + (return (list (<tag> (fold ++ (list) elems)))) + + _ + (fail (concat (list "[Parser Error] Unbalanced " <description> ".")))))) + + parse-form #&lexer:Close-Paren "parantheses" #Form + parse-tuple #&lexer:Close-Bracket "brackets" #Tuple + ) + +(def (parse-record parse) + (do [elems* (repeat parse) + token &lexer:lex + #let [elems (fold ++ (list) elems*)]] + (case token + #&lexer:Close-Bracket + (if (odd? (size elems)) + (fail "[Parser Error] Records must have an even number of elements.") + (return (list (#Record elems)))) + + _ + (fail "[Parser Error] Unbalanced braces.")))) + +;; [Interface] +(def parse + (do [token &lexer/lex] + (match token + (#&lexer:White-Space _) + (return (list)) + + (#&lexer:Comment _) + (return (list)) + + (#&lexer:Bool ?value) + (return (list [#Bool (jvm:invokestatic Boolean "parseBoolean" [String] [?value])])) + + (#&lexer:Int ?value) + (return (list [#Int (jvm:invokestatic Integer "parseInt" [String] [?value])])) + + (#&lexer:Real ?value) + (return (list [#Real (jvm:invokestatic Float "parseFloat" [String] [?value])])) + + (#&lexer:Char ?value) + (return (list [#Char (jvm:invokevirtual String "charAt" [int] ?value [0])])) + + (#&lexer:Text ?value) + (return (list [#Text ?value])) + + (#&lexer:Ident ?value) + (return (list [#Ident ?value])) + + (#&lexer:Tag ?value) + (return (list [#Tag ?value])) + + #&lexer:Open-Paren + (parse-form parse) + + #&lexer:Open-Bracket + (parse-tuple parse) + + #&lexer:Open-Brace + (parse-record parse) + ))) |