Radicalc  Check-in [2d65274902]

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

Overview
Comment:annotation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:2d6527490227d093ad85496668b6665aa5e8ece84bbcbe015ce4e0b3592de435
User & Date: athaudia 2017-08-28 20:07:00
Context
2017-08-28
21:25
intrinsic functions Leaf check-in: 906aaa2d5e user: athaudia tags: trunk
20:07
annotation check-in: 2d65274902 user: athaudia tags: trunk
2017-08-25
11:07
put ParseStep in it's own file check-in: 20fa3f4dc2 user: athaudia tags: trunk
Changes

Added src/AnnotateStep.cs.



















































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
using System;
using System.Collections.Generic;
using System.Linq;
#pragma warning disable 169, 649

class AnnotateStep {
	public class Type {
		public string name;
		public int size; //in bits
		public bool builtin;
	}

	static int var_id = 0;

	public class Variable {
		public string name; //maybe remove?, nah, lookup and debug
		public int id;
		public Type type;
		public bool is_parameter;
		public Variable(string name, Type type, bool is_parameter) {
			this.name = name;
			this.type = type;
			this.is_parameter = is_parameter;
			this.id = var_id++;
		}
	}

	public class Scope {
		public Scope parent;
		public List<Variable> variables = new List<Variable>();
	}

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

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

	public class Block {
		public Scope scope;
		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 varuse or member access
		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 StatementExpression : Statement {
		public Expression expression;		
	}

	public class Expression {
		public Type type;
	}

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

	public class ExpressionMemberAccess : Expression {
		//todo: hmms...?
	}

	public class ExpressionVariableUse : Expression {
		public Variable variable;
	}

	public class ExpressionIntLiteral : Expression {
		public string value;
	}

////////////////////////////////////////////////////////////////////////////////

	static void
	InitIntrinsics(Top top) {
		var t = top.types;
		t.Add(new Type{name = "i8",     size = 8,  builtin = true});
		t.Add(new Type{name = "i16",    size = 16, builtin = true});
		t.Add(new Type{name = "i32",    size = 32, builtin = true});
		t.Add(new Type{name = "i64",    size = 64, builtin = true});
		t.Add(new Type{name = "u8",     size = 8,  builtin = true});
		t.Add(new Type{name = "u16",    size = 16, builtin = true});
		t.Add(new Type{name = "u32",    size = 32, builtin = true});
		t.Add(new Type{name = "u64",    size = 64, builtin = true});
		t.Add(new Type{name = "string", size = -1, builtin = true});
		t.Add(new Type{name = "bool",   size = 1,  builtin = true});
	}

	static Type
	GetType(Top top, string name) {
		var t = top.types.First(item => item.name == name);
		if(t == null)
			throw new ArgumentOutOfRangeException("Unknown type: " + name);
		return t;
	}

	static Function
	GetFunction(Top top, string name, List<Type> pars) {
		foreach(var fun in top.functions) {
			if(fun.name == name && fun.parameters.Count == pars.Count) {
				for(var i = 0; i < pars.Count; ++i) {
					if(fun.parameters[i] != pars[i])
						break;
				}
				return fun;
			}
		}
		return null;
	}

	static Variable
	GetVariable(Scope scope, string name) {
		var v = scope.variables.FirstOrDefault(t => t.name == name);
		if(v == null) {
			if(scope.parent == null)
				throw new ArgumentOutOfRangeException("Unknown var: " + name);
			else
				return GetVariable(scope.parent, name);
		}
		return v;
	}

	static bool
	HasVariable(Scope scope, string name) { //not checking parent scopes
		var v = scope.variables.FirstOrDefault(t => t.name == name);
		return v != null;
	}

	public static Top
	Annotate(ParseStep.Top ptop) {
		var top = new Top();
		InitIntrinsics(top);
		var dict = new Dictionary<ParseStep.Function, Function>();
		//pre annotate functions(without their body)
		foreach(var pf in ptop.functions) {
			var scope = new Scope();
			var f = new Function {name = pf.name};
			f.type = GetType(top, pf.type.name);
			foreach(var pfp in pf.parameters) {
				var t = GetType(top, pfp.type.name);
				var v = new Variable(pfp.name, t, true);
				scope.variables.Add(v);
				f.parameters.Add(t);
			}
			f.block = new Block {scope = scope};
			top.functions.Add(f);
			dict[pf] = f;
		}

		//annotate bodies of functions
		foreach(var pf in ptop.functions) {
			var f = dict[pf];
			Annotate(pf.block, f.block, f, top);
		}
		return top;
	}

	public static void
	Annotate(ParseStep.Block pblock, Block block, Function fun, Top top) {
		var stmts = block.statements;
		foreach(var ps in pblock.statements) {
			switch(ps) {
			case ParseStep.StatementAssignment assign:
				var assign_l = Annotate(assign.left, top, block.scope);
				var assign_r = Annotate(assign.right, top, block.scope);
				if(assign_l.type != assign_r.type) {
					var msg = "can't assign "+assign_r.type.name+" to "+
						assign_l.type.name;
					throw new InvalidOperationException(msg);
				}
				stmts.Add(new StatementAssignment {
					left=assign_l,
					right=assign_r
				});
				break;
			case ParseStep.StatementIf psif:
				var sif = new StatementIf();
				sif.if_block = Annotate(psif.if_block, block.scope, fun, top);
				foreach(var pei in psif.elsif_blocks) {
					var b = Annotate(pei, block.scope, fun, top);
					sif.elsif_blocks.Add(b);
				}
				if(psif.else_block != null) {
					var b = new Block{scope = new Scope{parent = block.scope}};
					Annotate(psif.else_block, b, fun, top);
					sif.else_block = b;
				}
				stmts.Add(sif);
				break;
			case ParseStep.StatementWhile pwhile:
				var swhile = new StatementWhile();
				swhile.block = Annotate(pwhile.block, block.scope, fun, top);
				stmts.Add(swhile);
				break;
			case ParseStep.StatementReturn preturn:
				var e = Annotate(preturn.expression, top, block.scope);
				if(e.type != fun.type) {
					var m = "trying to return " + e.type.name;
					m += "but function is of type " + fun.type.name;
					throw new InvalidOperationException(m);
				}
				stmts.Add(new StatementReturn {expression = e});
				break;
			case ParseStep.StatementVardef pvdef:
				var t = GetType(top, pvdef.type.name);
				var v = new Variable(pvdef.variable, t, false);
				if(HasVariable(block.scope, pvdef.variable)) {
					var m = "variable "+pvdef.variable+" already exists";
					throw new InvalidOperationException(m);
				}
				block.scope.variables.Add(v);
				break;
			case ParseStep.StatementVardefAssignment pvdefa:
				var exp = Annotate(pvdefa.expression, top, block.scope);
				var va = new Variable(pvdefa.variable, exp.type, false);
				if(HasVariable(block.scope, pvdefa.variable)) {
					var m = "variable "+pvdefa.variable+" already exists";
					throw new InvalidOperationException(m);
				}
				block.scope.variables.Add(va);
				var st = new StatementAssignment();
				st.left = new ExpressionVariableUse(){variable=va};
				st.right = exp;
				stmts.Add(st);
				break;
			default:
				throw new InvalidOperationException("unknown statement type");
			}
		}
	}

	public static ConditionalBlock
	Annotate(ParseStep.ConditionalBlock pblock, Scope parent_scope,
	         Function fun, Top top)
	{
		var cond = Annotate(pblock.condition, top, parent_scope);
		if(cond.type != GetType(top, "bool"))
			throw new InvalidOperationException("condition must be bool");
		var block = new Block{scope = new Scope{parent = parent_scope}};
		Annotate(pblock.block, block, fun, top);
		return new ConditionalBlock{condition = cond, block = block};
	}

	public static Expression
	Annotate(ParseStep.Expression pexp, Top top, Scope scope) {
		switch(pexp) {
		case ParseStep.ExpressionFunctionCall pfuncall:
			var fun = new ExpressionFunctionCall();
			var types = new List<Type>();
			foreach(var ppar in pfuncall.parameters) {
				var par = Annotate(ppar, top, scope);
				fun.parameters.Add(par);
				types.Add(par.type);
			}
			fun.function = GetFunction(top, pfuncall.function, types);
			if(fun.function == null) {
				var m = "can't find function "+pfuncall.function+"(";
				foreach(var t in types)
					m += t.name+", ";
				m += ")";
				throw new InvalidOperationException(m);
			}
			return fun;
		case ParseStep.ExpressionMemberAccess pmember:
			var member = new ExpressionMemberAccess();
			throw new InvalidOperationException("nope");
			//todo: can't do yet, need to implement those types first :P
		case ParseStep.ExpressionVariableUse pvaruse:
			var varuse = new ExpressionVariableUse();
			varuse.variable = GetVariable(scope, pvaruse.variable);
			varuse.type = varuse.variable.type;
			return varuse;
		case ParseStep.ExpressionIntLiteral pintliteral:
			var intliteral = new ExpressionIntLiteral();
			intliteral.type = GetType(top, "i32");
			intliteral.value = pintliteral.value;
			return intliteral;
		default:
			throw new InvalidOperationException("unknown expression type");
		}
	}
}

Changes to src/Program.cs.

7
8
9
10
11
12
13
14
15
16
17
18
19


class Program {
	static void Main(String[] args) {
		var input  = CharStreams.fromPath("test.rcs");
		var lexer  = new RadicalcLexer(input);
		var tokens = new CommonTokenStream(lexer);
		var parser = new RadicalcParser(tokens);
		ParseStep.Top top = ParseStep.Parse(parser.top());
		foreach(var f in top.functions) {
			Console.WriteLine(f.name);
		}
	}
}








|
|
<
|


>
7
8
9
10
11
12
13
14
15

16
17
18
19

class Program {
	static void Main(String[] args) {
		var input  = CharStreams.fromPath("test.rcs");
		var lexer  = new RadicalcLexer(input);
		var tokens = new CommonTokenStream(lexer);
		var parser = new RadicalcParser(tokens);
		ParseStep.Top top1 = ParseStep.Parse(parser.top());
		AnnotateStep.Top top2 = AnnotateStep.Annotate(top1);

		
	}
}
//next step: implement AnnotateStep.GetFunction

Changes to src/stuff.txt.

1
2
3
4
5
6
7
8
9
10
11
..
78
79
80
81
82
83
84















85
86
semantic versioning of libraries
	-import statement: "import cool_library 2.4"
	only x and y of x.y.z needed
	matching any z, any y >= 4 and only x == 2

coding style
	-compiler has builtin formatter
	-80 columns
	-spaces only (inferior, but, less arguments, less confusion to beginners)

super basic "oop"
................................................................................
	  -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	


|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


1
2
3
4
5
6
7
8
9
10
11
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
semantic versioning of libraries
	-import statement: "import cool_library 2.4"
	-only x and y of x.y.z needed
	-matching any z, any y >= 4 and only x == 2

coding style
	-compiler has builtin formatter
	-80 columns
	-spaces only (inferior, but, less arguments, less confusion to beginners)

super basic "oop"
................................................................................
	  -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

namespace conflicts
	-priority system
	-first trying to resolve in the program code itself
	-then in all imported libraries
	-then at last in the standard library
	-that way adding new names to the standard library won't make current
	 code stop working, important for being able to add standard library
	 features in minor version number updates

unicode
	-source code must be 7-bit ascii
	-standard library will support some subset of unicode
	-utf8
	-prefered normalisation: nfc

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