push up:
[nedit-bw.git] / ParseFields3.diff
blob05c7ea9f6158246f52f93b5809a30e8cf0860910
1 Use the '.' operator as an array accessor
3 Available as a patch:
4 http://sourceforge.net/tracker/index.php?func=detail&aid=974211&group_id=11005&atid=311005
5 [ 974211 ] Use the '.' operator as an array accessor
6 ParseFields2.diff 2004-06-21 22:34
8 This allows you to view NEdit macro language arrays as records (both are
9 aggregates of heterogeneously typed objects). The only constraint is that
10 the accessor must appear like a valid symbol name, although internally it
11 is handled as a string. Thus the following statements are equivalent:
12 array["member"] = array["field"]
13 array.member = array.field
15 This implementation uses a flag, set when a '.' is scanned, to determine
16 whether the next identifier is a field - if so, it doesn't make a symbol
17 out of the identifier (leading to a variable in the resultant macro), but
18 instead returns a field token, which is just a constant string value used
19 as an index into the array.
21 ---
23 source/parse.y | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
24 1 files changed, 96 insertions(+), 1 deletion(-)
26 diff --quilt old/source/parse.y new/source/parse.y
27 --- old/source/parse.y
28 +++ new/source/parse.y
29 @@ -50,18 +50,22 @@ static Symbol *matchesActionRoutine(char
30 static char *ErrMsg;
31 static char *InPtr;
32 extern Inst *LoopStack[]; /* addresses of break, cont stmts */
33 extern Inst **LoopStackPtr; /* to fill at the end of a loop */
35 +static int nextSymIsField = 0;
36 + /* set to 1 when we don't want a full symbol, just a name (string) for a
37 + field name following a '.' */
41 %union {
42 Symbol *sym;
43 Inst *inst;
44 int nArgs;
46 -%token <sym> NUMBER STRING SYMBOL
47 +%token <sym> NUMBER STRING SYMBOL FIELD
48 %token DELETE ARG_LOOKUP
49 %token IF WHILE ELSE FOR BREAK CONTINUE RETURN
50 %type <nArgs> arglist catlist
51 %type <inst> cond comastmts for while else and or arrayexpr
52 %type <sym> evalsym
53 @@ -81,10 +85,11 @@ extern Inst **LoopStackPtr; /* to fill
54 %left '*' '/' '%'
55 %nonassoc UNARY_MINUS NOT
56 %nonassoc DELETE
57 %nonassoc INCR DECR
58 %right POW
59 +%left '.'
60 %nonassoc '['
61 %nonassoc '('
63 %% /* Rules */
65 @@ -178,10 +183,14 @@ simpstmt: SYMBOL '=' expr {
66 ADD_OP(OP_BIT_OR); ADD_OP(OP_ASSIGN); ADD_SYM($1);
68 | DELETE arraylv '[' arglist ']' {
69 ADD_OP(OP_ARRAY_DELETE); ADD_IMMED($4);
71 + | DELETE arraylv dot field {
72 + ADD_OP(OP_ARRAY_DELETE); ADD_IMMED(1);
73 + }
74 +/* array[index] assignment */
75 | initarraylv '[' arglist ']' '=' expr {
76 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
78 | initarraylv '[' arglist ']' ADDEQ expr {
79 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
80 @@ -236,10 +245,69 @@ simpstmt: SYMBOL '=' expr {
81 | DECR initarraylv '[' arglist ']' {
82 ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED($4);
83 ADD_OP(OP_DECR);
84 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($4);
86 +/* array.field assignment */
87 + | initarraylv dot field '=' expr {
88 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
89 + }
90 + | initarraylv dot field ADDEQ expr {
91 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
92 + ADD_OP(OP_ADD);
93 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
94 + }
95 + | initarraylv dot field SUBEQ expr {
96 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
97 + ADD_OP(OP_SUB);
98 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
99 + }
100 + | initarraylv dot field MULEQ expr {
101 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
102 + ADD_OP(OP_MUL);
103 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
105 + | initarraylv dot field DIVEQ expr {
106 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
107 + ADD_OP(OP_DIV);
108 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
110 + | initarraylv dot field MODEQ expr {
111 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
112 + ADD_OP(OP_MOD);
113 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
115 + | initarraylv dot field ANDEQ expr {
116 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
117 + ADD_OP(OP_BIT_AND);
118 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
120 + | initarraylv dot field OREQ expr {
121 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED(1);
122 + ADD_OP(OP_BIT_OR);
123 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
125 + | initarraylv dot field INCR {
126 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
127 + ADD_OP(OP_INCR);
128 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
130 + | initarraylv dot field DECR {
131 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
132 + ADD_OP(OP_DECR);
133 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
135 + | INCR initarraylv dot field {
136 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
137 + ADD_OP(OP_INCR);
138 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
140 + | DECR initarraylv dot field {
141 + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1);
142 + ADD_OP(OP_DECR);
143 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
145 | SYMBOL '(' arglist ')' {
146 ADD_OP(OP_SUBR_CALL);
147 ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
149 | INCR SYMBOL {
150 @@ -299,17 +367,32 @@ initarraylv: SYMBOL {
151 ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(1);
153 | initarraylv '[' arglist ']' {
154 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
156 + | initarraylv dot field {
157 + ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
160 arraylv: SYMBOL {
161 ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED(0);
163 | arraylv '[' arglist ']' {
164 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
166 + | arraylv dot field {
167 + ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
170 +field: FIELD {
171 + ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
173 + /* this bit allows things like array.5 for array[5] **
174 + | NUMBER {
175 + ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
177 + */
179 arrayexpr: numexpr {
180 $$ = GetPC();
183 @@ -338,10 +421,13 @@ numexpr: NUMBER {
184 ADD_OP(OP_PUSH_ARG_ARRAY);
186 | numexpr '[' arglist ']' {
187 ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
189 + | numexpr dot field {
190 + ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
192 | numexpr '+' numexpr {
193 ADD_OP(OP_ADD);
195 | numexpr '-' numexpr {
196 ADD_OP(OP_SUB);
197 @@ -441,10 +527,14 @@ and: AND {
198 or: OR {
199 ADD_OP(OP_DUP); ADD_OP(OP_BRANCH_TRUE); $$ = GetPC();
200 ADD_BR_OFF(0);
203 +dot: '.' %prec '.' {
204 + nextSymIsField = 1;
207 blank: /* nothing */
208 | blank '\n'
211 %% /* User Subroutines Section */
212 @@ -561,10 +651,15 @@ static int yylex(void)
213 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
214 if (!strcmp(symName, "define")) {
215 InPtr -= 6;
216 return 0;
218 + if (nextSymIsField) {
219 + nextSymIsField = 0;
220 + yylval.sym = InstallStringConstSymbol(symName);
221 + return FIELD;
223 if ((s=LookupSymbol(symName)) == NULL) {
224 s = InstallSymbol(symName, symName[0]=='$' ?
225 (((symName[1] > '0' && symName[1] <= '9') && symName[2] == 0) ?
226 ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);
227 s->value.tag = NO_TAG;