@@ -4,6 +4,7 @@ import std.conv;
44import std.range ;
55import std.stdio ;
66import std.format ;
7+ import std.algorithm ;
78import callisto.error;
89import callisto.parser;
910
@@ -28,12 +29,20 @@ class StackCheckerError : Exception {
2829}
2930
3031class StackChecker {
31- Word[string ] words;
32- StackCell[] stack;
33- string [] identifiers;
32+ Word[string ] words;
33+ StackCell[] stack;
34+ string [] identifiers;
35+ string [][string ] structs;
3436
3537 this () {
36-
38+ structs[" Array" ] = [" length" , " memberSize" , " elements" ];
39+ structs[" Exception" ] = [" error" , " msg" ];
40+
41+ foreach (key, structure ; structs) {
42+ foreach (ref member ; structure) {
43+ identifiers ~= format(" %s.%s" , key, member);
44+ }
45+ }
3746 }
3847
3948 void ErrorNoThrow (Char, A... )(ErrorInfo error, in Char[] fmt, A args) {
@@ -105,10 +114,10 @@ class StackChecker {
105114 Pop(node, word.effect.pop);
106115 Push(node, word.effect.push);
107116 }
117+ else if (identifiers.canFind(node.name)) {
118+ Push(node, 1 );
119+ }
108120 else {
109- foreach (key, value ; words) {
110- writeln(key);
111- }
112121 Error(node.error, " Unknown word '%s'" , node.name);
113122 }
114123 }
@@ -120,18 +129,25 @@ class StackChecker {
120129
121130 auto oldStack = stack;
122131 stack = [];
132+ auto oldIdentifiers = identifiers.dup ;
123133
124134 if (node.manual) {
125135 Push(node, node.params.length);
126136 }
137+ else {
138+ foreach (ref param ; node.params) {
139+ identifiers ~= param;
140+ }
141+ }
127142
128143 Evaluate(node.nodes);
129144
130145 if (stack.length > node.returnTypes.length) {
131146 StackOverflow(node, node.returnTypes.length);
132147 }
133148
134- stack = oldStack;
149+ stack = oldStack;
150+ identifiers = oldIdentifiers;
135151 }
136152
137153 void EvaluateIf (IfNode node) {
@@ -260,6 +276,23 @@ class StackChecker {
260276 stack = oldStack;
261277 }
262278
279+ void EvaluateStruct (StructNode node) {
280+ string [] structure;
281+ foreach (ref member ; node.members) {
282+ structure ~= member.name;
283+ }
284+
285+ if (node.name in structs) {
286+ Error(node.error, " Structure '%s' already exists" , node.name);
287+ }
288+
289+ structs[node.name] = structure;
290+
291+ foreach (ref member ; structure) {
292+ identifiers ~= format(" %s.%s" , node.name, member);
293+ }
294+ }
295+
263296 void EvaluateNode (Node node) {
264297 switch (node.type) {
265298 case NodeType.Word: EvaluateWord(cast (WordNode) node); break ;
@@ -280,6 +313,7 @@ class StackChecker {
280313 case NodeType.Implement: EvaluateImplement(cast (ImplementNode) node); break ;
281314 case NodeType.Set: Pop(node, 1 ); break ;
282315 case NodeType.TryCatch: EvaluateTryCatch(cast (TryCatchNode) node); break ;
316+ case NodeType.Struct: EvaluateStruct(cast (StructNode) node); break ;
283317 default : break ;
284318 }
285319 }
0 commit comments