summaryrefslogtreecommitdiff
path: root/grammar
blob: 0bb9406eb442d1a4ef02fb4994aa6ea1dbc55704 (plain) (blame)
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
root: module-decl top-level*;

module-decl: "module" ident ";";
top-level: def-bind ";";

def-bind: "def" decl-list "=" expr-list;

decl-list: (ident expr? ",")* ident expr?;
expr-list: (expr ",")* expr;

expr
	: ident
	| number
	| string
	| function-proto
	| function
	| function-call
	| expr "^" /* Pointer Dereference */
	| unary-op expr
	| expr binary-op expr
	| "(" expr ")"
	;

function: function-proto block-statement;
function-call: expr "(" expr-list? ")";
function-proto: "func" "(" decl-list? ")" (expr | "(" expr-list ")")?;

block-statement: "{" statement* "}";
statement
	: block-statement
	| (expr
	  | def-bind
	  | expr-list "=" expr-list
	  | "return" expr-list?
	  )?
	  ";"
	;

unary-op
	: "^" /* Pointer */
	| "~"
	| "+"
	| "-"
	| "&"
	;

binary-op
	: "+"
	| "-"
	| "*"
	| "/"
	| "%"  /* Remainder */
	| "%%" /* Modulus */
	| "~"  /* XOR */
	| "&"
	| "|"
	| "&~" /* Bitwise-ANDNOT */
	| "<<"
	| "<<<" /* Left Rotate */
	| ">>"
	| ">>>" /* Right Rotate */
	| "&&"
	| "||"
	| "=="
	| "!="
	| "<="
	| ">="
	| "<"
	| ">"
	;

ident: xid-start xid-continue*;
xid-start
	: \p{XID_Start}
	| "_"
	| "$"
	;
xid-continue
	: \p{XID_Continue}
	| "′"
	| "″"
	| "‴"
	| "⁗"
	;

string: "\"" string-part+ "\"";
string-part: [^"] | "\\\"";

number
	: number-bin
	| number-oct
	| number-dec
	| number-hex
	;

number-bin: "#b"  number-rest<[01]>;
number-oct: "#o"  number-rest<[01234567>;
number-dec: "#d"? number-rest<[0123456789]>;
number-hex: "#x"  number-rest<[0123456789ABCDEF]>;

(* <a> is the alphabet *)
number-rest<a>: (number-word<a> ("." number-word<a>?)?
                | "." number-word<a>)
				("e" [-+] number-word<a>)?;
number-word<a>: <a> ((<a> | "'")* <a>)?;