aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-13 21:51:04 +0200
committerBad Diode <bd@badd10de.dev>2024-06-13 21:51:04 +0200
commitdeaf192df939c9ec9a62ef4febaf76ade0dcbb01 (patch)
treecdce9ce0179702b29c8d88a540f80b577882e9a0 /README.md
parent2f738a73790258514f86614ba9a9591578a5bdf0 (diff)
downloadbdl-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.md181
1 files changed, 159 insertions, 22 deletions
diff --git a/README.md b/README.md
index b5681c8..512ebee 100644
--- a/README.md
+++ b/README.md
@@ -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```
44program : <statement>* EOF 44; Support for multiple return values, some options:
45 45
46<statement> : <definition> | <expression> 46fn 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 50fn 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> ) 55fn 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
71let a:s32 124
72let a:s32
73 124
74let
75 a:s32
76 124
77let
78 a:s32 124
79
80; What happens if we make a mistake and use let over let?
81let a:s32 let b:u32 c
82; or
83let a:s32 <missing value here>
84let b:u32 c
85; well since, we have an expression that evaluates to nil it should be fine
86
87if x == 2 {
88 ; expressions
89}
90
91if (x == 2) foo()
92
93if
94 true {
95 ; expressions
96 }
97 else {
98 ; expressions
99 }
100
101if
102 (x == 2) if (x != 1) else 2
103 (x == 3) bar()
104
105if (x == 1) (foo x y)
106if (x == 2) foo(x y)
107if (x == 3) bar()
108if (x == 4) baz()
109if (x == 5) "literals too"
110
111match symbol
112 case 5 "block"
113 case 32 foo()
114 case 49 "alsd asdlk aslkdf alskdf"
115
116match (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
121cond (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