Radicalc  Check-in [ed4ffd2b88]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:ParseStep done'ish
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:ed4ffd2b884978c3c1e0540a81d1ca6d35f55b52976f6fbfa67006f98d3ffd6b
User & Date: athaudia 2017-08-25 03:30:33
Context
2017-08-25
11:07
put ParseStep in it's own file check-in: 20fa3f4dc2 user: athaudia tags: trunk
03:30
ParseStep done'ish check-in: ed4ffd2b88 user: athaudia tags: trunk
2017-08-23
17:05
switching to antlr and c# check-in: cb3c0872e3 user: athaudia tags: trunk
Changes

Changes to src/Program.cs.

1

2


3

4
5



6








































































































































































































































































































7
8
9
10
11
12
13
14
15





16

17

using System;

using Antlr4.Runtime;


[assembly: CLSCompliant(false)]


class Listener : RadicalcBaseListener {



	








































































































































































































































































































}

class Program {
	static void Main(String[] args) {
		Console.WriteLine("Yay!");
		var input  = CharStreams.fromPath("test.rcs");
		var lexer  = new RadicalcLexer(input);
		var tokens = new CommonTokenStream(lexer);
		var parser = new RadicalcParser(tokens);





	}

}


>

>
>

>

<
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>
>
>
>
>
|
>
|
>
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;
[assembly: CLSCompliant(false)]
#pragma warning disable 649


class ParseStep {
	public class Top {
		public List<Function> functions = new List<Function>();
	}

	public class Type {
		public String name;
	}

	public class Function {
		public class Parameter {
			public String name;
			public Type type;
		}
		public String name;
		public Type type;
		public List<Parameter> parameters = new List<Parameter>();
		public Block block;
	}

	public class Block {
		public List<Statement> statements = new List<Statement>();
	}

	public class ConditionalBlock {
		public Expression condition;
		public Block block;
	}

	public class Statement {
		
	}

	public class StatementAssignment : Statement {
		public Expression left; //only member access or varuse legal
		public Expression right;
	}

	public class StatementIf : Statement {
		public ConditionalBlock if_block;
		public List<ConditionalBlock> elsif_blocks =
			new List<ConditionalBlock>();
		public Block else_block;
	}

	public class StatementWhile : Statement {
		public ConditionalBlock block;
	}

	public class StatementReturn : Statement {
		public Expression expression;
	}

	public class StatementVardef : Statement {
		public String variable;
		public Type type;
	}

	public class StatementVardefAssignment : Statement {
		public String variable;
		public Expression expression;
	}

	public class StatementExpression : Statement {
		public Expression expression;
	}

	public class Expression {
		
	}

	public class ExpressionFunctionCall : Expression {
		public String function;
		public List<Expression> parameters = new List<Expression>();
	}

	public class ExpressionMemberAccess : Expression {
		public Expression left;
		public String member;
	}

	public class ExpressionVariableUse : Expression {
		public String variable;
	}

	public class ExpressionIntLiteral : Expression {
		public String value;
	}


	public static Top
	Parse(RadicalcParser.TopContext c) {
		var top = new Top();
		foreach(var fun in c.fundef()) {
			top.functions.Add(Parse(fun));
		}
		return top;	
	}

	public static Function
	Parse(RadicalcParser.FundefContext c) {
		var fun = new Function{name = c.IDENT().ToString()};
		var pars = c.fundef_params();
		if(pars != null) {
			foreach(var par in pars.fundef_param()) {
				fun.parameters.Add(Parse(par));
			}
		}
		fun.type = Parse(c.type());
		fun.block = Parse(c.block());
		return fun;
	}

	public static Function.Parameter
	Parse(RadicalcParser.Fundef_paramContext c) {
		return new Function.Parameter {
			name = c.IDENT().ToString(),
			type = Parse(c.type())
		};
	}

	public static Type
	Parse(RadicalcParser.TypeContext c) {
		//todo: more complex types
		return new Type{name = c.IDENT().ToString()};
	}

	public static Block
	Parse(RadicalcParser.BlockContext c) {
		var block = new Block();
		foreach(var s in c.statement()) {
			block.statements.Add(Parse(s));
		}
		return block;
	}

	public static Statement
	Parse(RadicalcParser.StatementContext c) {
		if(c.assign_stmt() != null)
			return Parse(c.assign_stmt());
		else if(c.if_stmt() != null)
			return Parse(c.if_stmt());
		else if(c.while_stmt() != null)
			return Parse(c.while_stmt());
		else if(c.return_stmt() != null)
			return Parse(c.return_stmt());
		else if(c.vardef() != null)
			return Parse(c.vardef());
		else if(c.expr() != null)
			return new StatementExpression {
				expression = Parse(c.expr())
			};
		else
			throw new NotImplementedException("unknown statement type");
	}

	public static Statement
	Parse(RadicalcParser.Assign_stmtContext c) {
		//todo: member variables
		return new StatementAssignment {
			left = Parse(c.assign_stmt_left()),
			right = Parse(c.expr())
		};
	}

	public static Expression
	Parse(RadicalcParser.Assign_stmt_leftContext c) {
		switch(c) {
		case RadicalcParser.Assign_stmt_left_simpleContext simp:
			return new ExpressionVariableUse {
				variable = simp.IDENT().ToString()
			};
		case RadicalcParser.Assign_stmt_left_memberContext memb:
			return new ExpressionMemberAccess {
				left = Parse(memb.expr()),
				member = memb.IDENT().ToString()
			};
		}
		throw new InvalidOperationException();
	}

	public static Statement
	Parse(RadicalcParser.If_stmtContext c) {
		var s = new StatementIf();
		s.if_block = new ConditionalBlock {
			condition = Parse(c.expr()),
			block = Parse(c.block())
		};
		foreach(var ei in c.if_stmt_elsif()) {
			s.elsif_blocks.Add(new ConditionalBlock {
				condition = Parse(ei.expr()),
				block = Parse(ei.block())
			});
		}
		if(c.if_stmt_else() != null)
			s.else_block = Parse(c.if_stmt_else().block());
		return s;
	}

	public static Statement
	Parse(RadicalcParser.While_stmtContext c) {
		return new StatementWhile {
			block = new ConditionalBlock {
				condition = Parse(c.expr()),
				block = Parse(c.block())
			}
		};
	}

	public static Statement
	Parse(RadicalcParser.Return_stmtContext c) {
		return new StatementReturn {
			expression = Parse(c.expr())
		};
	}

	public static Statement
	Parse(RadicalcParser.VardefContext c) {
		switch(c) {
		case RadicalcParser.Vardef_simpleContext simp:
			return new StatementVardef {
				variable = simp.IDENT().ToString(),
				type = Parse(simp.type())
			};
		case RadicalcParser.Vardef_assignContext assign:
			return new StatementVardefAssignment {
				variable = assign.IDENT().ToString(),
				expression = Parse(assign.expr())
			};
		}
		throw new InvalidOperationException();
	}

	private static ExpressionFunctionCall
	Op(String name, Expression p1, Expression p2) {
		var e = new ExpressionFunctionCall { function = name };
		e.parameters.Add(p1);
		e.parameters.Add(p2);
		return e;
	}
	
	public static Expression
	Parse(RadicalcParser.ExprContext c) {
		switch(c) {
		case RadicalcParser.Expr_memberContext member:
			return new ExpressionMemberAccess {
				left = Parse(member.expr()),
				member = member.IDENT().ToString()
			};
		case RadicalcParser.Expr_muldivContext muldiv:
			if(muldiv.MUL() != null)
				return Op("mul", Parse(muldiv.expr(0)), Parse(muldiv.expr(1)));
			else
				return Op("div", Parse(muldiv.expr(0)), Parse(muldiv.expr(1)));
		case RadicalcParser.Expr_addsubContext addsub:
			if(addsub.PLUS() != null)
				return Op("add", Parse(addsub.expr(0)), Parse(addsub.expr(1)));
			else
				return Op("sub", Parse(addsub.expr(0)), Parse(addsub.expr(1)));
		case RadicalcParser.Expr_cmpContext cmp:
			if(cmp.CMP_LT() != null)
				return Op("cmp_lt", Parse(cmp.expr(0)), Parse(cmp.expr(1)));
			else if(cmp.CMP_LEQ() != null)
				return Op("cmp_leq", Parse(cmp.expr(0)), Parse(cmp.expr(1)));
			else if(cmp.CMP_GT() != null)
				return Op("cmp_gt", Parse(cmp.expr(0)), Parse(cmp.expr(1)));
			else
				return Op("cmp_geq", Parse(cmp.expr(0)), Parse(cmp.expr(1)));
		case RadicalcParser.Expr_cmpeqContext eq:
			if(eq.CMP_EQ() != null)
				return Op("cmp_eq", Parse(eq.expr(0)), Parse(eq.expr(1)));
			else
				return Op("cmp_neq", Parse(eq.expr(0)), Parse(eq.expr(1)));
		case RadicalcParser.Expr_andContext and:
			return Op("and", Parse(and.expr(0)), Parse(and.expr(1)));
		case RadicalcParser.Expr_orContext or:
			return Op("or", Parse(or.expr(0)), Parse(or.expr(1)));
		case RadicalcParser.Expr_parenContext paren:
			return Parse(paren.expr());
		case RadicalcParser.Expr_funcallContext funcall:
			var f = new ExpressionFunctionCall {
				function = funcall.IDENT().ToString()	
			};
			if(funcall.funcall_params() != null) {
				foreach(var p in funcall.funcall_params().expr())
					f.parameters.Add(Parse(p));
			}
			return f;
		case RadicalcParser.Expr_arrayContext a:
			return Op("subscript", Parse(a.expr(0)), Parse(a.expr(1)));
		case RadicalcParser.Expr_varuseContext v:
			return new ExpressionVariableUse {variable = v.IDENT().ToString()};
		case RadicalcParser.Expr_intlitContext intlit:
			return new ExpressionIntLiteral {
				value = intlit.INT_LITERAL().ToString()
			};
		}
		Console.WriteLine(c.GetType().FullName);
		throw new InvalidOperationException();
	}
}

class Program {
	static void Main(String[] args) {
		Console.WriteLine("Yay!");
		var input  = CharStreams.fromPath("test.rcs");
		var lexer  = new RadicalcLexer(input);
		var tokens = new CommonTokenStream(lexer);
		var parser = new RadicalcParser(tokens);
		var tree = parser.top();
		//AstTop top = (AstTop)visitor.Visit(tree);
		ParseStep.Top top = ParseStep.Parse(tree);
		foreach(var f in top.functions) {
			Console.WriteLine(f.name);
		}
		//ParseTreeWalker.Default.Walk(listener, tree);
	}
}

Changes to src/Radicalc.g4.

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
    CLASS IDENT (IS IDENT)? NL (IDENT COLON type NL)* END;

fundef:
    FUN IDENT PAREN_OPEN fundef_params? PAREN_CLOSE COLON type? NL
    block END;

fundef_params:



    IDENT COLON type (COMMA IDENT COLON type)*;

block:
    (statement NL)*;

statement: assign_stmt | if_stmt | while_stmt| return_stmt | vardef | expr;

assign_stmt:
    (IDENT | expr DOT IDENT) EQUALS expr; //todo: hmms repeating the . stuff :(





if_stmt:



    IF expr NL block (ELSIF expr NL block)* (ELSE NL block)? END;




while_stmt:
    WHILE expr NL block END;

return_stmt:
    RETURN expr;

vardef:
    VAR IDENT COLON type
|   VAR IDENT EQUALS expr;

expr:
    expr DOT IDENT
|   expr (MUL | DIV) expr
|   expr (PLUS | MINUS) expr
|   expr (CMP_LT | CMP_LEQ | CMP_GT | CMP_GEQ) expr
|   expr (CMP_EQ | CMP_NEQ) expr
|   expr AND expr
|   expr OR expr
|   PAREN_OPEN expr PAREN_CLOSE
|   IDENT PAREN_OPEN funcall_params? PAREN_CLOSE
|   IDENT BRACK_OPEN expr BRACK_CLOSE
|   IDENT
|   INT_LITERAL;


funcall_params:
    expr (COMMA expr)*;


type:
    IDENT
|   BRACK_OPEN type BRACK_CLOSE
|   PAREN_OPEN type (COMMA type)* PAREN_CLOSE; //always atleast one type in there... the return type







>
>
>
|




|


|

>
>
>
>

>
>
>
|
>
>
>








|
|


|
|
|
|
|
|
|
|
|
|
|
|
>









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
    CLASS IDENT (IS IDENT)? NL (IDENT COLON type NL)* END;

fundef:
    FUN IDENT PAREN_OPEN fundef_params? PAREN_CLOSE COLON type? NL
    block END;

fundef_params:
    fundef_param (COMMA fundef_param)*;

fundef_param:
	IDENT COLON type;

block:
    (statement NL)*;

statement: assign_stmt | if_stmt | while_stmt | return_stmt | vardef | expr;

assign_stmt:
    assign_stmt_left EQUALS expr; //todo: hmms repeating the . stuff :(

assign_stmt_left:
	IDENT          # assign_stmt_left_simple
|	expr DOT IDENT # assign_stmt_left_member;

if_stmt:
    IF expr NL block if_stmt_elsif* if_stmt_else? END;

if_stmt_elsif:
	ELSIF expr NL block;

if_stmt_else:
	ELSE NL block;

while_stmt:
    WHILE expr NL block END;

return_stmt:
    RETURN expr;

vardef:
    VAR IDENT COLON type  # vardef_simple
|   VAR IDENT EQUALS expr # vardef_assign;

expr:
    expr DOT IDENT                                  # expr_member
|   expr (MUL | DIV) expr                           # expr_muldiv
|   expr (PLUS | MINUS) expr                        # expr_addsub
|   expr (CMP_LT | CMP_LEQ | CMP_GT | CMP_GEQ) expr # expr_cmp
|   expr (CMP_EQ | CMP_NEQ) expr                    # expr_cmpeq
|   expr AND expr                                   # expr_and
|   expr OR expr                                    # expr_or
|   PAREN_OPEN expr PAREN_CLOSE                     # expr_paren
|   IDENT PAREN_OPEN funcall_params? PAREN_CLOSE    # expr_funcall
|   expr BRACK_OPEN expr BRACK_CLOSE                # expr_array
|   IDENT                                           # expr_varuse
|   INT_LITERAL                                     # expr_intlit
;

funcall_params:
    expr (COMMA expr)*;


type:
    IDENT
|   BRACK_OPEN type BRACK_CLOSE
|   PAREN_OPEN type (COMMA type)* PAREN_CLOSE; //always atleast one type in there... the return type

Changes to src/build.bat.

1
2
3
4
5
6
REM nearleyc radicalc.ne -o parser.js
REM clang++ main.cpp -fuse-ld=lld -lucrt.lib -o radicalc.exe && radicalc.exe
REM call "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
REM cd "c:\dev\radicalc\src"
REM cl main.cpp && main.exe
java -jar \apps\antlr-4.7-complete.jar -o gen -Dlanguage=CSharp Radicalc.g4





|
1
2
3
4
5
6
REM nearleyc radicalc.ne -o parser.js
REM clang++ main.cpp -fuse-ld=lld -lucrt.lib -o radicalc.exe && radicalc.exe
REM call "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
REM cd "c:\dev\radicalc\src"
REM cl main.cpp && main.exe
java -jar \apps\antlr-4.7-complete.jar -visitor -o gen -Dlanguage=CSharp Radicalc.g4

Changes to src/stuff.txt.

30
31
32
33
34
35
36

37
38
39
40
41
42
43
..
71
72
73
74
75
76
77





78
79
80
	-i32(bla:Object) to convert from Object to i32, aborts program if wrong type
	-works with custom types too

arrays
	-value semantics, but backed by heap
	-dynamic
	-type being something like :[i32]


strings
	-value semantics, but backed by heap
	-hmm... mutable or immutable?
	-mutable would make them more like arrays, so less confusion happens

function pointer
................................................................................
	  -each thread gets a copy of static_data, which is read only
	  -each thread grabs itself an element of the task_data
	    -index that is atomically incremented and read, as sync primitive
	  -each thread calls function with static_data and task_data[idx]
	  -the return of the function gets written into results[idx]
	  -goto grab element of task_data, and repeat until idx >= length(task_data)
	  -when all threads are done, return results






nopes
	-no for loops(for now), extra syntax that is just shorthand in the end	







>







 







>
>
>
>
>



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
	-i32(bla:Object) to convert from Object to i32, aborts program if wrong type
	-works with custom types too

arrays
	-value semantics, but backed by heap
	-dynamic
	-type being something like :[i32]
	-multi-dimensional arrays maybe?

strings
	-value semantics, but backed by heap
	-hmm... mutable or immutable?
	-mutable would make them more like arrays, so less confusion happens

function pointer
................................................................................
	  -each thread gets a copy of static_data, which is read only
	  -each thread grabs itself an element of the task_data
	    -index that is atomically incremented and read, as sync primitive
	  -each thread calls function with static_data and task_data[idx]
	  -the return of the function gets written into results[idx]
	  -goto grab element of task_data, and repeat until idx >= length(task_data)
	  -when all threads are done, return results

ast-based format for source(faaaar future)
	-syntax would just be the presentation layer of the editor
	-could be displayed in a text style
	-could be displayed more graphically

nopes
	-no for loops(for now), extra syntax that is just shorthand in the end