(use ./util #as &util #refer [do return fail try-all repeat]) (use ./lexer #as &lexer) ;; [Utils] (do-template [ ] (def ( parse) (do [elems (repeat parse) token &lexer:lex] (case token (return (list ( (fold ++ (list) elems)))) _ (fail (concat (list "[Parser Error] Unbalanced " ".")))))) 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) )))