aboutsummaryrefslogtreecommitdiff
path: root/source/luxc/parser.lux
blob: 35ec12b17ca5e6594509f59c8e6e99946349aba6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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)
      )))