-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMicron_Programming_Language.ebnf
249 lines (166 loc) · 7.71 KB
/
Micron_Programming_Language.ebnf
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
// Copyright (c) 2024, 2025 by Rochus Keller <mailto:me@rochus-keller.ch>
//
// GNU General Public License Usage
// This file may be used under the terms of the GNU General Public
// License (GPL) versions 2.0 or 3.0 as published by the Free Software
// Foundation and appearing in the file LICENSE.GPL included in
// the packaging of this file. Please review the following information
// to ensure GNU General Public Licensing requirements will be met:
// http://www.fsf.org/licensing/licenses/info/GPLv2.html and
// http://www.gnu.org/copyleft/gpl.html.
// To consider in future:
// - smart pointers (i.e. a separate pointer type) with garbage collection (AUTOPTR, SMARTPTR, REF, ?)
// - Go interfaces for object types
// - set language level directly in source code? in module header or via directive?
#define LEVEL1
#define LEVEL3
Micron ::= module
ident ::= // ( letter | '_' ) {letter | digit | '_'}
integer ::= // digit {hexDigit|'_'} ['O'|'B'|'H'] ['U'|'U8'|'U16'|'U32'|'U64'|'I'|'I8'|'I16'|'I32'|'I64']
real ::= // digit {digit|'_'} '.' {digit} [('E' | 'D' | 'F' ) ['+' | '-'] digit {digit}]
number ::= integer | real
string ::= // '"' {character} '"'
hexchar ::= // digit {hexDigit} 'X'
hexstring ::= // '$' {hexDigit} '$'
comment- ::= '(*' '*)' '//'
Comment ::=
directive- ::= '<*' '*>' // oadkwood source code directive
hexstringdelim- ::= '$'
qualident ::= [ \LL:2\ ident '.' ] ident
identdef ::= ident [ '*' | '-' ]
ConstDeclaration ::= identdef (
'=' ConstExpression
| ':' NamedType // for each CONST meta param, and only there, whereas same ident
)
ConstExpression ::= expression
TypeDeclaration ::= identdef '=' type
type ::= NamedType | ArrayType | RecordType | PointerType | ProcedureType | enumeration
#ifdef LEVEL3
| ObjectType
#endif
NamedType ::= qualident
ArrayType ::= ARRAY [ length ] OF type | '[' [ length ] ']' type
length ::= ConstExpression | VAR expression
RecordType ::= RECORD [FixedPart] [VariantPart] END
#ifdef LEVEL3
ObjectType ::= OBJECT ['(' BaseType ')'] { IdentList ':' type [ ';' ] } END // no inlines, case, nor bitfields
BaseType ::= NamedType
#endif
inline_ ::= INLINE | IN
VariantPart ::= CASE { ['|'] [inline_] identdef ':' type }
FixedPart ::= FieldList [ ';' ] { FieldList [ ';' ] }
FieldList ::= IdentList ':' type [ BITS integer ] // in contrast to C, type only affects current fields
| '..' BITS integer // use to add padding bits; as in C, 0 starts a new unit
| inline_ identdef ':' type
IdentList ::= identdef { [','] identdef}
PointerType ::= (POINTER TO | '^') type // any type in Micron, also simple or procedure types
enumeration ::= '(' constEnum ')'
constEnum ::= ident [ '=' ConstExpression ] { [','] ident }
VariableDeclaration ::= IdentList ':' type
designator ::= qualident {selector}
selector ::= '.' ident | '[' expression ']' | '^' | '(' [ ExpList ] ')'
ExpList ::= expression { [','] expression }
expression ::= SimpleExpression [ relation SimpleExpression ]
relation ::= '=' | '#' | '<>' | '<' | '<=' | '>' | '>=' | IN
#ifdef LEVEL3
| IS
#endif
SimpleExpression ::= ['+' | '-'] term { AddOperator term }
AddOperator ::= '+' | '-' | OR
term ::= factor {MulOperator factor}
MulOperator ::= '*' | '/' | DIV | MOD | '&' | AND
literal ::= number | string | hexstring | hexchar | NIL | TRUE | FALSE
constructor ::= [NamedType] '{' [ component {[','] component} ] '}'
component ::=
\LL:2\ ident ':' expression // explicit record field name (ident is like a label, thus ':')
| '[' ConstExpression ']' ':' expression // explicit array element
| expression ['..' expression] // value mapped to record or array by field/element order; '..' only for sets
factor ::=
\LA: 1:ident & 2:'{'\ constructor
| literal
| variableOrFunctionCall // replaces: designator [ActualParameters]
| '(' expression ')'
| ('~'| NOT) factor // negation
| '@' designator // address of operator
variableOrFunctionCall ::= designator // designator includes [ ActualParameters ]
statement ::=
\LA: 1:ident & 2:':'\ gotoLabel
| assignmentOrProcedureCall
| IfStatement | CaseStatement |
LoopStatement |
ExitStatement | GotoStatement |
ReturnStatement |
WhileStatement | RepeatStatement | ForStatement
assignmentOrProcedureCall ::= designator [
':=' expression ] // assignment
// designator enthält neu auch Params: | [ ActualParameters ] // ProcedureCall
StatementSequence ::= { ';' } { statement { ';' } }
gotoLabel ::= ident ':'
GotoStatement ::= GOTO ident
IfStatement ::= IF expression THEN StatementSequence { ElsifStatement }
[ ElseStatement ] END
ElsifStatement ::= ELSIF expression THEN StatementSequence
ElseStatement ::= ELSE StatementSequence
CaseStatement ::= CASE expression OF [Case] { '|' Case }
[ ELSE StatementSequence ] END
Case ::= CaseLabelList ':' StatementSequence
CaseLabelList ::= LabelRange { [','] LabelRange }
LabelRange ::= label [ '..' label ]
label ::= ConstExpression
WhileStatement ::= WHILE expression DO StatementSequence END
RepeatStatement ::= REPEAT StatementSequence UNTIL expression
ForStatement ::= FOR ident ':=' expression TO expression [ BY ConstExpression ]
DO StatementSequence END
// no WithStatement in Micron
LoopStatement ::= LOOP StatementSequence END
ExitStatement ::= EXIT
procedure ::= PROCEDURE | PROC
ProcedureType ::= procedure
#ifdef LEVEL3
[\LL:2\'(' ( POINTER | '^' ) ')'] // type-bound procedure type, includes an object pointer
#endif
[FormalParameters]
ProcedureDeclaration ::=
\LL:2\ procedure '^' identdef [ FormalParameters ] [INLINE | INVAR | EXTERN]
| ProcedureHeading ( [INLINE | INVAR] [ ';' ] ProcedureBody | \LL:2\ [ ';' ] EXTERN [ident] )
ProcedureHeading ::= procedure
#ifdef LEVEL3
[ Receiver | \LL:2\ ident '.' ]
#endif
identdef [ FormalParameters ]
#ifdef LEVEL3
Receiver ::= '(' ident ':' ident ')' // right ident is either a pointer or object type, which doesn't matter
#endif
block ::= BEGIN StatementSequence
#ifdef LEVEL1
[ FINALLY StatementSequence ]
#endif
ProcedureBody ::= DeclarationSequence block END ident
DeclarationSequence ::=
{ CONST { ConstDeclaration [';'] }
| TYPE { TypeDeclaration [';'] }
| VAR { VariableDeclaration [';'] }
| ProcedureDeclaration [';'] }
ReturnStatement ::= RETURN
[ expression ] // leads to LL(k) ambig with qualident statement; resolve by checking if proc has return type
FormalParameters ::= '(' [ FPSection { \LA: 1:(ident|'CONST') | (2:';' & 3:(ident|'CONST'))\
[';'] FPSection } [ [';'] '..'] ] ')' [ ':' ReturnType ]
ReturnType ::= [POINTER TO | '^'] NamedType
FPSection ::= [CONST] ident { [','] ident } ':' FormalType
FormalType ::= type
module ::= MODULE ident [ MetaParams ] [';']
{ ImportList | DeclarationSequence }
[ block ] END ident ['.']
ImportList ::= IMPORT import { [ ',' ] import } [';']
import ::= [ \LL:2\ ident ':=' ] ident
{ '.' ident } // NOTE: paths are not case sensitive
[ MetaActuals ]
MetaActuals ::= '(' ConstExpression { [','] ConstExpression } ')'
MetaParams ::= '(' MetaSection { [';'] MetaSection } ')'
MetaSection ::= [ TYPE | CONST ] ident { \LL:2\ [','] ident } [ ':' NamedType ]
reserved_for_future_extensions- ::= 'AUTOPTR' OBJECT IS FINALLY INTERFACE
/// Pragmas
%module ::= 'Micron'
%namespace ::= 'Mic'
%suppress ::= ';' ',' '.' ':'
%no_syntree ::= 'true'