Basic: QBasic fixes/enabling. Recursive includes.
[jackhill/mal.git] / basic / env.in.bas
1
2 REM ENV_NEW(C) -> R
3 ENV_NEW:
4 REM allocate the data hashmap
5 GOSUB HASHMAP
6 AY=R
7
8 REM set the outer and data pointer
9 T=13:L=R:M=C:GOSUB ALLOC
10 GOSUB RELEASE: REM environment takes ownership
11 RETURN
12
13 REM see RELEASE types.in.bas for environment cleanup
14
15 REM ENV_NEW_BINDS(C, A, B) -> R
16 ENV_NEW_BINDS:
17 GOSUB ENV_NEW
18 E=R
19 REM process bindings
20 ENV_NEW_BINDS_LOOP:
21 IF Z%(A+1)=0 THEN R=E:RETURN
22 REM get/deref the key from A
23 K=Z%(A+2)
24
25 IF S$(Z%(K+1))="&" THEN GOTO EVAL_NEW_BINDS_VARGS
26
27 EVAL_NEW_BINDS_1x1:
28 REM get/deref the key from B
29 C=Z%(B+2)
30 REM set the binding in the environment data
31 GOSUB ENV_SET
32 REM go to next element of A and B
33 A=Z%(A+1)
34 B=Z%(B+1)
35 GOTO ENV_NEW_BINDS_LOOP
36
37 EVAL_NEW_BINDS_VARGS:
38 REM get/deref the key from next element of A
39 A=Z%(A+1)
40 K=Z%(A+2)
41 REM the value is the remaining list in B
42 A=B:T=6:GOSUB FORCE_SEQ_TYPE
43 C=R
44 REM set the binding in the environment data
45 GOSUB ENV_SET
46 R=E
47 AY=C:GOSUB RELEASE: REM list is owned by environment
48 RETURN
49
50 REM ENV_SET(E, K, C) -> R
51 ENV_SET:
52 H=Z%(E+1)
53 GOSUB ASSOC1
54 Z%(E+1)=R
55 R=C
56 RETURN
57
58 REM ENV_SET_S(E, B$, C) -> R
59 ENV_SET_S:
60 H=Z%(E+1)
61 GOSUB ASSOC1_S
62 Z%(E+1)=R
63 R=C
64 RETURN
65
66 REM ENV_FIND(E, K) -> R
67 REM Returns environment (R) containing K. If found, value found is
68 REM in R4
69 SUB ENV_FIND
70 T=E
71 ENV_FIND_LOOP:
72 H=Z%(T+1)
73 REM More efficient to use GET for value (R) and contains? (R3)
74 GOSUB HASHMAP_GET
75 REM if we found it, save value in R4 for ENV_GET
76 IF R3=1 THEN R4=R:R=T:GOTO ENV_FIND_DONE
77 T=Z%(T+2): REM get outer environment
78 IF T>0 THEN GOTO ENV_FIND_LOOP
79 R=-1
80 ENV_FIND_DONE:
81 END SUB
82
83 REM ENV_GET(E, K) -> R
84 ENV_GET:
85 CALL ENV_FIND
86 IF R=-1 THEN ER=-1:E$="'"+S$(Z%(K+1))+"' not found":GOTO ENV_GET_RETURN
87 R=R4
88 GOSUB INC_REF_R
89 GOTO ENV_GET_RETURN