@@ -42,6 +42,7 @@ public import SCode;
4242
4343protected import Error ;
4444protected import List ;
45+ protected import NFLookup ;
4546protected import Util ;
4647
4748public uniontype Entry
@@ -110,6 +111,17 @@ algorithm
110111 ENV (scopes = outEnv :: _) := inEnv;
111112end exitScope;
112113
114+ public function exitScopes
115+ input Env inEnv;
116+ input Integer inScopes;
117+ output Env outEnv;
118+ algorithm
119+ outEnv := match(inEnv, inScopes)
120+ case (_, 0 ) then inEnv;
121+ else exitScopes(exitScope(inEnv), inScopes - 1 );
122+ end match;
123+ end exitScopes;
124+
113125public function topScope
114126 input Env inEnv;
115127 output Env outEnv;
@@ -130,6 +142,26 @@ algorithm
130142 outEnv := List . last(scopes);
131143end builtinScope;
132144
145+ public function isTopScope
146+ input Env inEnv;
147+ output Boolean outIsTopScope;
148+ algorithm
149+ outIsTopScope := match(inEnv)
150+ case ENV (scopes = {_}) then true ;
151+ else false ;
152+ end match;
153+ end isTopScope;
154+
155+ public function isBuiltinScope
156+ input Env inEnv;
157+ output Boolean outIsBuiltinScope;
158+ algorithm
159+ outIsBuiltinScope := match(inEnv)
160+ case ENV (scopes = {}) then true ;
161+ else false ;
162+ end match;
163+ end isBuiltinScope;
164+
133165public function makeEntry
134166 input SCode . Element inElement;
135167 input Env inEnv;
@@ -194,8 +226,12 @@ algorithm
194226 then
195227 inEnv;
196228
197- case (ENTRY (scopeLevel = scope_lvl), ENV (scopes = scopes))
198- then listGet(scopes, scope_lvl);
229+ case (ENTRY (scopeLevel = scope_lvl),
230+ ENV (scopeCount = scope_count, scopes = scopes))
231+ equation
232+ scope_lvl = scope_count - scope_lvl;
233+ then
234+ listGet(scopes, scope_lvl);
199235
200236 end matchcontinue;
201237end entryEnv;
@@ -270,14 +306,39 @@ algorithm
270306 ENTRY (element = outElement) := inEntry;
271307end entryElement;
272308
273- public function scopeNameList
309+ public function isClassEntry
310+ input Entry inEntry;
311+ output Boolean outIsClass;
312+ algorithm
313+ outIsClass := match(inEntry)
314+ case ENTRY (element = SCode . CLASS (name = _)) then true ;
315+ else false ;
316+ end match;
317+ end isClassEntry;
318+
319+ public function scopeName
320+ input Env inEnv;
321+ output String outString;
322+ algorithm
323+ outString := match(inEnv)
324+ local
325+ String name;
326+
327+ case ENV (name = SOME (name)) then name;
328+ case ENV (scopes = {}) then "<builtin>" ;
329+ else "<global>" ;
330+
331+ end match;
332+ end scopeName;
333+
334+ public function scopeNames
274335 input Env inEnv;
275336 output list< String > outNames;
276337algorithm
277- outNames := scopeNameList2 (inEnv, {});
278- end scopeNameList ;
338+ outNames := scopeNames2 (inEnv, {});
339+ end scopeNames ;
279340
280- public function scopeNameList2
341+ protected function scopeNames2
281342 input Env inEnv;
282343 input list< String > inAccumNames;
283344 output list< String > outNames;
@@ -288,27 +349,123 @@ algorithm
288349 Env env;
289350
290351 case (ENV (name = SOME (name), scopes = env :: _), _)
291- then scopeNameList2 (env, name :: inAccumNames);
352+ then scopeNames2 (env, name :: inAccumNames);
292353
293354 case (ENV (scopes = env :: _), _)
294- then scopeNameList2 (env, inAccumNames);
355+ then scopeNames2 (env, inAccumNames);
295356
296357 case (ENV (name = SOME (name), scopes = {}), _)
297- then listReverse( name :: inAccumNames) ;
358+ then name :: inAccumNames;
298359
299360 case (ENV (scopes = {}), _)
300- then listReverse( inAccumNames) ;
361+ then inAccumNames;
301362
302363 end match;
303- end scopeNameList2;
364+ end scopeNames2;
365+
366+ public function envPath
367+ input Env inEnv;
368+ output Absyn . Path outPath;
369+ algorithm
370+ outPath := match(inEnv)
371+ local
372+ String name;
373+ Absyn . Path path;
374+ Env env;
375+
376+ case ENV (name = SOME (name), scopes = ENV (name = NONE ()) :: _)
377+ then Absyn . IDENT (name);
378+
379+ case ENV (name = SOME (name))
380+ equation
381+ env = exitScope(inEnv);
382+ path = envPath(env);
383+ then
384+ Absyn . QUALIFIED (name, path);
385+
386+ end match;
387+ end envPath;
388+
389+ public function prefixIdentWithEnv
390+ input String inIdent;
391+ input Env inEnv;
392+ output Absyn . Path outPath;
393+ protected
394+ list< String > strl;
395+ algorithm
396+ strl := listReverse(scopeNames(inEnv));
397+ strl := inIdent :: strl;
398+ outPath := Absyn . stringListPathReversed(strl);
399+ end prefixIdentWithEnv;
400+
401+ public function isEqual
402+ "Checks if two environments are equal, with regards to the scope names."
403+ input Env inEnv1;
404+ input Env inEnv2;
405+ output Boolean outIsEqual;
406+ algorithm
407+ outIsEqual := matchcontinue(inEnv1, inEnv2)
408+ local
409+ String n1, n2;
410+ Env rest1, rest2;
411+
412+ case (ENV (name = SOME (n1)), ENV (name = SOME (n2)))
413+ equation
414+ false = stringEq(n1, n2);
415+ then
416+ false ;
417+
418+ case (ENV (scopes = {}), ENV (scopes = {})) then true ;
419+
420+ else
421+ equation
422+ rest1 = exitScope(inEnv1);
423+ rest2 = exitScope(inEnv2);
424+ then
425+ isEqual(rest1, rest2);
426+
427+ end matchcontinue;
428+ end isEqual;
429+
430+ public function isPrefix
431+ "Checks if one environment is a prefix of another."
432+ input Env inPrefixEnv;
433+ input Env inEnv;
434+ output Boolean outIsPrefix;
435+ algorithm
436+ outIsPrefix := matchcontinue(inPrefixEnv, inEnv)
437+ local
438+ String n1, n2;
439+ Env rest1, rest2;
440+ Integer sc1, sc2, sc_diff;
441+
442+ // If the first environment has more scopes than the second, then it can't
443+ // be a prefix.
444+ case (ENV (scopeCount = sc1), ENV (scopeCount = sc2))
445+ equation
446+ true = intGt(sc1, sc2);
447+ then
448+ false ;
449+
450+ // Otherwise, remove scopes from the second environment until they are the
451+ // same length, and check if they are equal or not.
452+ case (ENV (scopeCount = sc1), ENV (scopeCount = sc2))
453+ equation
454+ sc_diff = sc2 - sc1;
455+ rest2 = exitScopes(inEnv, sc_diff);
456+ then
457+ isEqual(inPrefixEnv, rest2);
304458
459+ end matchcontinue;
460+ end isPrefix;
461+
305462public function printEnvPathStr
306463 input Env inEnv;
307464 output String outString;
308465protected
309466 list< String > scopes;
310467algorithm
311- scopes := scopeNameList (inEnv);
468+ scopes := scopeNames (inEnv);
312469 outString := stringDelimitList(scopes, "." );
313470end printEnvPathStr;
314471
@@ -343,7 +500,7 @@ algorithm
343500 encapsulatedPrefix = ep, classDef = cdef)), _)
344501 equation
345502 env = openScope(SOME (name), ep, inEnv);
346- env = populateEnvWithClassDef(cdef, env);
503+ env = populateEnvWithClassDef(cdef, env, env );
347504 then
348505 env;
349506
@@ -359,16 +516,20 @@ end enterEntryScope;
359516protected function populateEnvWithClassDef
360517 input SCode . ClassDef inClassDef;
361518 input Env inEnv;
519+ input Env inAccumEnv;
362520 output Env outEnv;
363521algorithm
364- outEnv := match(inClassDef, inEnv)
522+ outEnv := match(inClassDef, inEnv, inAccumEnv )
365523 local
366- list< SCode . Element > elems;
524+ list< SCode . Element > elems, comps, cls, exts, imps ;
367525 Env env;
368526
369- case (SCode . PARTS (elementLst = elems), _)
527+ case (SCode . PARTS (elementLst = elems), _, env )
370528 equation
371- env = List . fold(elems, populateEnvWithElement, inEnv);
529+ (comps, cls, exts, imps, _) = SCode . partitionElements(elems);
530+ env = List . fold(comps, insertElement, env);
531+ env = List . fold(cls, insertElement, env);
532+ env = List . fold1(exts, populateEnvWithExtends, inEnv, env);
372533 then
373534 env;
374535
@@ -381,32 +542,48 @@ algorithm
381542 end match;
382543end populateEnvWithClassDef;
383544
384- protected function populateEnvWithElement
385- input SCode . Element inElement ;
545+ protected function populateEnvWithExtends
546+ input SCode . Element inExtends ;
386547 input Env inEnv;
387- output Env outEnv;
548+ input Env inAccumEnv;
549+ output Env outAccumEnv;
388550algorithm
389- outEnv := match(inElement , inEnv)
551+ outAccumEnv := match(inExtends , inEnv, inAccumEnv )
390552 local
391553 Entry entry;
392554 Env env;
555+ Absyn . Path bc;
556+ Absyn . Info info;
393557
394- case (SCode . EXTENDS (baseClassPath = _) , _)
558+ case (SCode . EXTENDS (baseClassPath = bc, info = info), _ , _)
395559 equation
396- print("NFEnv.populateEnvWithElement: EXTENDS! \n " );
560+ (entry, env) = NFLookup . lookupBaseClassName(bc, inEnv, info);
561+ env = populateEnvWithEntry(entry, env, inAccumEnv);
397562 then
398- fail();
563+ env;
564+
565+ end match;
566+ end populateEnvWithExtends;
399567
400- case (SCode . IMPORT (imp = _), _)
568+ protected function populateEnvWithEntry
569+ input Entry inEntry;
570+ input Env inEnv;
571+ input Env inAccumEnv;
572+ output Env outEnv;
573+ algorithm
574+ outEnv := match(inEntry, inEnv, inAccumEnv)
575+ local
576+ SCode . ClassDef cdef;
577+ Env env;
578+
579+ case (ENTRY (element = SCode . CLASS (classDef = cdef)), _, _)
401580 equation
402- print( "NFEnv.populateEnvWithElement: IMPORT! \n " );
581+ env = populateEnvWithClassDef(cdef, inEnv, inAccumEnv );
403582 then
404- fail();
405-
406- else insertElement(inElement, inEnv);
583+ env;
407584
408585 end match;
409- end populateEnvWithElement ;
586+ end populateEnvWithEntry ;
410587
411588// AVL Tree implementation
412589public type AvlKey = String ;
@@ -493,6 +670,9 @@ algorithm
493670 // then
494671 // fail();
495672
673+ case (AVLTREENODE (height = h, left = left, right = right), 0 , key, value)
674+ then AVLTREENODE (SOME (AVLTREEVALUE (key, value)), h, left, right);
675+
496676 // Insert into right subtree.
497677 case (AVLTREENODE (value = oval, height = h, left = left, right = right),
498678 1 , key, value)
0 commit comments