File: pictureSyntax.bs

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (136 lines) | stat: -rw-r--r-- 3,367 bytes parent folder | download | duplicates (4)
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
use core:lang;
use lang:bs;
use lang:bs:macro;
use layout;

class PictureBlock on Compiler {
	// Root block.
	private ExprBlock root;

	// Sub-block, so that we can put the return statement last.
	ExprBlock sub;

	// Variable for accessing the picture object being created.
	LocalVarAccess me;

	// Counter for generating unique identifiers.
	private Nat unique;

	// Create.
	init(SrcPos pos, Block parent) {
		ExprBlock root(pos, parent);
		ExprBlock sub(pos, root);

		Var me(root, SStr("picture"), namedExpr(root, name{presentation:Picture}, Actuals()));
		root.add(me);
		root.add(sub);
		root.add(LocalVarAccess(pos, me.var));

		init() {
			root = root;
			sub = sub;
			me = LocalVarAccess(pos, me.var);
		}
	}

	// Generate a variable name.
	Str uniqueName() { "@ node${unique++}"; }

	// Get the block.
	ExprBlock block() { root; }

	// Add an expression.
	void add(Expr expr) {
		sub.add(expr);
	}
}

class PictureElem on Compiler {
	// The block we insert things into.
	private ExprBlock into;

	// The variable we created in the parent block.
	LocalVarAccess me;

	// Create.
	init(SStr var, SrcName create, Actuals params, PictureBlock parent) {
		ExprBlock into(create.pos, parent.sub);
		Expr created = namedExpr(parent.sub, create, params);
		Var v(parent.sub, var, created);
		parent.add(v);
		parent.add(into);

		init() {
			into = into;
			me(create.pos, v.var);
		}

		parent.add(namedExpr(parent.sub, SStr("add"), parent.me, Actuals(me)));
	}

	// Set a property.
	void set(SStr name, Actuals? params) {
		Actuals p = if (params) { params; } else { Actuals(); };
		if (e = findProperty(name, p)) {
			into.add(e);
		} else {
			throw SyntaxError(name.pos, "No suitable property '${name.v}' found for ${me.result} (parameters: ${p})");
		}
	}

	// Generate a call for the property if it exists.
	private Expr? findProperty(SStr name, Actuals params) {
		Expr e = namedExpr(into, name, me, params);
		unless (e as UnresolvedName) {
			return e;
		}

		// If more than one parameter, we can't do assignment.
		if (params.expressions.count != 1) {
			return null;
		}

		// TODO: Consider calling the constructor of whatever type 'l' is, if we found something.
		Expr l = namedExpr(into, name, me, Actuals());
		if (l as UnresolvedName) {
			return null;
		}

		AssignOpInfo assign(SStr("=", name.pos), 10, true);
		return assign.meaning(into, l, params.expressions[0]);
	}

	// Get the block.
	ExprBlock block() { into; }
}

PictureElem pictureElem(SrcPos pos, SrcName create, Actuals params, PictureBlock parent) {
	PictureElem(SStr(parent.uniqueName, pos), create, params, parent);
}


// Create a layout block from a picture block.
package LayoutBlock asLayoutBlock(LayoutRoot parent, PictureBlock p) on Compiler {
	var pBlock = p.block;

	ExprBlock wrap(pBlock.pos, parent.block);
	Var v(wrap, SStr("@ picture"), namedExpr(pBlock, SStr("component"), Actuals(pBlock)));
	wrap.add(v);

	LayoutBlock(wrap, pBlock, LocalVarAccess(pBlock.pos, v.var));
}

// Special case for 'of' syntax.
void place(PictureElem to, SrcName dir, Expr distance, Expr origin) {
	Actuals a;
	a.add(namedExpr(to.block, dir, Actuals()));
	a.add(distance);
	a.add(origin);
	to.set(SStr("place", dir.pos), a);
}

// Special case for animation syntax.
void set(PictureElem to, AniDecl ani) {
	ani.finalize();
	to.set(SStr("animation", ani.block.pos), Actuals(ani.block));
}