summaryrefslogtreecommitdiffstats
path: root/parser.y
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-10-20 06:40:07 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-10-20 06:40:07 -0700
commitb67f0c623feb14ff27e1c70ef192163dd31b8945 (patch)
tree1a3e609992df73a78ac88feb7c3d61ea6becf80c /parser.y
parent86523c667aceef602f80034d18edf68ee2949a11 (diff)
downloadtxr-b67f0c623feb14ff27e1c70ef192163dd31b8945.tar.gz
txr-b67f0c623feb14ff27e1c70ef192163dd31b8945.tar.bz2
txr-b67f0c623feb14ff27e1c70ef192163dd31b8945.zip
Fix struct lit problem exposed by circular syntax.
The semantics of how struct literals come to life is poorly designed: namely, the slot-value pairs in the struct literal are used as the plist argument in a call to make-struct. This is wrong because the implied initializations are then clobbered by the structure type's :init and :postinit handlers, resulting in an object with slot values that don't match what is in the literal. When you add circular syntax to the mix, things get worse. Slots may be initialized with (sys:circ-ref ...) expressions corresponding to #<n># syntax. These expressions then get clobbered by the constructor actions before the circ_backpatch processes the syntax. * parser.y (struct): Use make_struct_lit rather than make_struct to instantiate struct object. * struct.tl (sys:struct-lit): Expand to a form which calls sys:make-struct-lit, rather than make-struct. * struct.c (struct_init): Register new make_struct_lit function as sys:make-struct-lit intrinsic. (make_struct_lit): New function. * struct.h (make_struct_lit): Declared. * tests/012/struct.tl: struct literal expansion test case updated. * txr.1: Updated documentation of struct literals. Added compat notes.
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y6
1 files changed, 2 insertions, 4 deletions
diff --git a/parser.y b/parser.y
index c3bc60e5..953a942d 100644
--- a/parser.y
+++ b/parser.y
@@ -825,10 +825,8 @@ struct : HASH_S list { if (unquotes_occur($2, 0))
$$ = rl(cons(struct_lit_s, $2),
num($1));
else
- { args_decl(args, 0);
- val strct = make_struct(first($2),
- rest($2),
- args);
+ { val strct = make_struct_lit(first($2),
+ rest($2));
$$ = rl(strct, num($1)); } }
;