Use the '.' operator as an array accessor Available as a patch: http://sourceforge.net/tracker/index.php?func=detail&aid=974211&group_id=11005&atid=311005 [ 974211 ] Use the '.' operator as an array accessor ParseStringEscapes.diff 2004-06-16 16:47 This allows you to view NEdit macro language arrays as records (both are aggregates of heterogeneously typed objects). The only constraint is that the accessor must appear like a valid symbol name, although internally it is handled as a string. Thus the following statements are equivalent: array["member"] = array["field"] array.member = array.field This implementation suffers from the slight inconvenience of creating extraneous symbols in the macro function's symbol table: for the expression above, extra symbols member and field will have corresponding variables on the stack. (It should be possible to work around this in future.) diff -ur nedit_official/source/parse.y nedit_mod/source/parse.y --- nedit_official/source/parse.y 2003-12-19 18:23:31.000000000 -0500 +++ nedit_mod/source/parse.y 2004-06-15 11:53:18.531303000 -0400 @@ -42,6 +42,7 @@ static int yyerror(char *s); static int yylex(void); int yyparse(void); +static Symbol *symbolToString(const Symbol *sym); static int follow(char expect, int yes, int no); static int follow2(char expect1, int yes1, char expect2, int yes2, int no); static int follow_non_whitespace(char expect, int yes, int no); @@ -83,6 +84,7 @@ %nonassoc DELETE %nonassoc INCR DECR %right POW +%left '.' %nonassoc '[' %nonassoc '(' @@ -180,6 +182,10 @@ | DELETE arraylv '[' arglist ']' { ADD_OP(OP_ARRAY_DELETE); ADD_IMMED((void *)$4); } + | DELETE arraylv '.' field { + ADD_OP(OP_ARRAY_DELETE); ADD_IMMED((void *)1); + } +/* array[index] assignment */ | initarraylv '[' arglist ']' '=' expr { ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } @@ -238,6 +244,65 @@ ADD_OP(OP_DECR); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$4); } +/* array.field assignment */ + | initarraylv '.' field '=' expr { + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field ADDEQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_ADD); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field SUBEQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_SUB); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field MULEQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_MUL); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field DIVEQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_DIV); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field MODEQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_MOD); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field ANDEQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_BIT_AND); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field OREQ expr { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)1); + ADD_OP(OP_BIT_OR); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field INCR { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)1); + ADD_OP(OP_INCR); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | initarraylv '.' field DECR { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)1); + ADD_OP(OP_DECR); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | INCR initarraylv '.' field { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)1); + ADD_OP(OP_INCR); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } + | DECR initarraylv '.' field { + ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)1); + ADD_OP(OP_DECR); + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)1); + } | SYMBOL '(' arglist ')' { ADD_OP(OP_SUBR_CALL); ADD_SYM(PromoteToGlobal($1)); ADD_IMMED((void *)$3); @@ -294,6 +359,9 @@ | initarraylv '[' arglist ']' { ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)$3); } + | initarraylv '.' field { + ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)1); + } ; arraylv: SYMBOL { ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED((void *)0); @@ -301,6 +369,18 @@ | arraylv '[' arglist ']' { ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)$3); } + | arraylv '.' field { + ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)1); + } + ; +field: SYMBOL { + ADD_OP(OP_PUSH_SYM); ADD_SYM(symbolToString($1)); + } + /* this bit allows things like array.5 for array[5] ** + | NUMBER { + ADD_OP(OP_PUSH_SYM); ADD_SYM($1); + } + */ ; arrayexpr: numexpr { $$ = GetPC(); @@ -333,6 +413,9 @@ | numexpr '[' arglist ']' { ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)$3); } + | numexpr '.' field { + ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)1); + } | numexpr '+' numexpr { ADD_OP(OP_ADD); } @@ -616,6 +699,15 @@ } /* +** Use the symbol's identifier name as a string +*/ + +static Symbol *symbolToString(const Symbol *sym) +{ + return InstallStringConstSymbol(sym->name); +} + +/* ** look ahead for >=, etc. */ static int follow(char expect, int yes, int no)