diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-13 21:51:04 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-13 21:51:04 +0200 |
commit | deaf192df939c9ec9a62ef4febaf76ade0dcbb01 (patch) | |
tree | cdce9ce0179702b29c8d88a540f80b577882e9a0 /README.md | |
parent | 2f738a73790258514f86614ba9a9591578a5bdf0 (diff) | |
download | bdl-deaf192df939c9ec9a62ef4febaf76ade0dcbb01.tar.gz bdl-deaf192df939c9ec9a62ef4febaf76ade0dcbb01.zip |
Testing some ideas for a new grammar... for a new lang
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 181 |
1 files changed, 159 insertions, 22 deletions
@@ -41,29 +41,166 @@ compiled natively, meaning it should be possible to call `bdl` code from `C` and | |||
41 | # Grammar | 41 | # Grammar |
42 | 42 | ||
43 | ``` | 43 | ``` |
44 | program : <statement>* EOF | 44 | ; Support for multiple return values, some options: |
45 | 45 | ||
46 | <statement> : <definition> | <expression> | 46 | fn foo_name(arg1 :u8, arg2 :u16) :u32, :str { |
47 | 47 | ; foo body... returns a tuple of two elements | |
48 | <definition> : ( def <symbol> <expression> ) | 48 | } |
49 | | ( fun <symbol> ( <symbol>* ) <body> ) | 49 | |
50 | 50 | fn foo_name(arg1:u8, arg2:u16):(u32, str) { | |
51 | <expression> : <constant> | 51 | ; foo body... returns a tuple of two elements |
52 | | ( lambda ( <symbol>* ) <body> ) | 52 | } |
53 | | ( if <expression> <expression> <expression> ) | 53 | |
54 | | ( if <expression> <expression> ) | 54 | ; Support for default function names maybe |
55 | | ( set! <symbol> <expression> ) | 55 | fn foo_name( |
56 | | ( <expression> <expression>* ) | 56 | arg1: u8 |
57 | 57 | arg2: u16 | |
58 | <body> : <statement>* | 58 | arg3: u16 |
59 | 59 | arg4: u16 = 52 | |
60 | <constant> : <bool> | <number> | <string> | <symbol> | 60 | arg5: u16 |
61 | arg6: u16 | ||
62 | ): (u32 str) { | ||
63 | ; foo body... returns a tuple of two elements. | ||
64 | ; commas could be syntax sugar, converting to whitespace during parsing. | ||
65 | } | ||
66 | |||
67 | ; Everything is an expression, including functions and variable definitions, | ||
68 | ; which evaluate to `nil`. | ||
69 | |||
70 | ; All of these could be equivalent | ||
71 | let a:s32 124 | ||
72 | let a:s32 | ||
73 | 124 | ||
74 | let | ||
75 | a:s32 | ||
76 | 124 | ||
77 | let | ||
78 | a:s32 124 | ||
79 | |||
80 | ; What happens if we make a mistake and use let over let? | ||
81 | let a:s32 let b:u32 c | ||
82 | ; or | ||
83 | let a:s32 <missing value here> | ||
84 | let b:u32 c | ||
85 | ; well since, we have an expression that evaluates to nil it should be fine | ||
86 | |||
87 | if x == 2 { | ||
88 | ; expressions | ||
89 | } | ||
90 | |||
91 | if (x == 2) foo() | ||
92 | |||
93 | if | ||
94 | true { | ||
95 | ; expressions | ||
96 | } | ||
97 | else { | ||
98 | ; expressions | ||
99 | } | ||
100 | |||
101 | if | ||
102 | (x == 2) if (x != 1) else 2 | ||
103 | (x == 3) bar() | ||
104 | |||
105 | if (x == 1) (foo x y) | ||
106 | if (x == 2) foo(x y) | ||
107 | if (x == 3) bar() | ||
108 | if (x == 4) baz() | ||
109 | if (x == 5) "literals too" | ||
110 | |||
111 | match symbol | ||
112 | case 5 "block" | ||
113 | case 32 foo() | ||
114 | case 49 "alsd asdlk aslkdf alskdf" | ||
115 | |||
116 | match (symbol or literal) | ||
117 | case (symbol or literal) block | ||
118 | case (symbol or literal) foo() | ||
119 | case (symbol or literal) "alsd asdlk aslkdf alskdf" | ||
120 | |||
121 | cond (10 == 1) { | ||
122 | |||
123 | ~a << b & 10 | ||
124 | |||
125 | } | ||
126 | ``` | ||
61 | 127 | ||
62 | <bool> : true | false | 128 | ``` |
63 | <number> : -?<digit>+ | 129 | <literal> ::= <boolean> | <number> | <string> | <nil> |
64 | <string> : " <character>+ " | 130 | |
65 | <digit> : 0 | 1 | ... | 9 | 131 | /* any unicode rune really really */ |
66 | <symbol> : <character>+ | 132 | <character> ::= [a-z] | [A-Z] |
133 | <string> ::= "\"" <character>+ "\"" | ||
134 | <comment> ::= ";" <character>* | ||
135 | /* notably the symbol can't be a reserved word or start with a numeric value, modify later */ | ||
136 | <symbol> ::= <character>+ | ||
137 | <nil> ::= "nil" | ||
138 | |||
139 | /* boolean literals */ | ||
140 | <boolean> ::= "true" | "false" | ||
141 | |||
142 | /* numbers TODO: Missing imaginary numbers (for the future maybe?) */ | ||
143 | <number> ::= <integer> | <real> | ||
144 | <fractional> ::= <digit>+ "." <digit>+ | ||
145 | <real> ::= ("+" | "-")? <fractional> | ||
146 | | ("+" | "-")? <fractional> ("e" | "E") ("+" | "-")? <digit>+ | ||
147 | <integer> ::= ("+" | "-")? <digit>+ | ||
148 | | "0b" [0-1]+ | ||
149 | | "0x" ([0-9] | [a-f])+ | ||
150 | <digit> ::= [0-9] | ||
151 | |||
152 | /* conditional expressions */ | ||
153 | <condition> ::= <expression> | "else" | ||
154 | |||
155 | <case> ::= "case" <literal> <expression> | ||
156 | <conditional> ::= "if" (<condition> <expression>)+ | ||
157 | | "match" <expression> <case>+ | ||
158 | |||
159 | /* variables and functions */ | ||
160 | <vardecl> ::= "let" <symbol> <type>? ("=" <expression>)? | ||
161 | | "let" "(" (<symbol> <type>? ("=" <expression>)?)+ ")" | ||
162 | |||
163 | <fundecl> ::= "fun" <symbol> "(" <argument>* ")" <type>* <expression> | ||
164 | <argument> ::= <symbol> <type>? ("=" <literal>)? | ||
165 | <type> ::= ":" <symbol> | ||
166 | <funcall> ::= <symbol> ("." <symbol>)? "(" <expression>+ ")" | ||
167 | <flowchange> ::= "return" ("(" <expression>+ ")")? | ||
168 | | "continue" | "break" | ||
169 | |||
170 | <loop> ::= "while" <expression> <expression> | ||
171 | | "while" <vardecl> <expression> <expression> | ||
172 | |||
173 | <assignment> ::= "set" <symbol> "=" <expression> | ||
174 | | "set" "(" (<symbol> "=" <expression>)+ ")" | ||
175 | |||
176 | <expression> ::= <equality> | ||
177 | <equality> ::= <comparison> ( ( "!=" | "==" ) <comparison>)* | ||
178 | <comparison> ::= <term> ( ( ">" | ">=" | "<" | "<=" ) <term>)* | ||
179 | <term> ::= <factor> ( ( "-" | "+" ) <factor>)* | ||
180 | <factor> ::= <logical> (("/" | "*") <logical>)* | ||
181 | <logical> ::= <unary> (("and" | "or") <unary>)* | ||
182 | <unary> ::= "!" <unary> | <bitlogic> | ||
183 | <bitlogic> ::= <bitshift> (("&" | "|") <bitshift>)* | ||
184 | <bitshift> ::= <bitneg> (("<<" | ">>") <bitneg>)* | ||
185 | <bitneg> ::= "~" <bitneg> | <primary> | ||
186 | <primary> ::= <literal> | ||
187 | | <symbol> | ||
188 | | <funcall> | ||
189 | | <conditional> | ||
190 | | <loop> | ||
191 | | <block> | ||
192 | | <flowchange> | ||
193 | | <assignment> | ||
194 | | "(" <expression> ")" | ||
195 | |||
196 | <structdecl> ::= "struct" <symbol> "{" ((<symbol> <type> ("=" <literal>)?) <fundecl>)+ "}" | ||
197 | |||
198 | <declaration> ::= <fundecl> | <vardecl> | <structdecl> | <expression> | ||
199 | |||
200 | <block> ::= "{" <declaration>+ "}" | ||
201 | <program> ::= <declaration>+ "EOF" | ||
202 | |||
203 | /* TODO: Missing arithmetic and logic operations, type declarations */ | ||
67 | ``` | 204 | ``` |
68 | 205 | ||
69 | # Resources | 206 | # Resources |