1.1 --- a/generator.py Mon Feb 04 18:53:56 2019 +0100
1.2 +++ b/generator.py Mon May 20 13:12:25 2019 +0200
1.3 @@ -854,6 +854,7 @@
1.4 typedef struct {
1.5 const __table * table;
1.6 __pos pos;
1.7 + int temporary;
1.8 __attr attrs[%s];
1.9 %s
1.10 } %s;
1.11 @@ -882,6 +883,7 @@
1.12 %s %s = {
1.13 &%s,
1.14 %s,
1.15 + 0, /* not temporary */
1.16 {
1.17 %s
1.18 },
2.1 --- a/templates/native/common.c Mon Feb 04 18:53:56 2019 +0100
2.2 +++ b/templates/native/common.c Mon May 20 13:12:25 2019 +0200
2.3 @@ -1,6 +1,6 @@
2.4 /* Common operations for native functions.
2.5
2.6 -Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
2.7 +Copyright (C) 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
2.8
2.9 This program is free software; you can redistribute it and/or modify it under
2.10 the terms of the GNU General Public License as published by the Free Software
2.11 @@ -30,9 +30,9 @@
2.12 {
2.13 /* Create a new string and mutate the __data__, __size__ and __key__ attributes. */
2.14 __attr attr = __NEWINSTANCE(__builtins___str_string);
2.15 - __store_via_object(__VALUE(attr), __data__, (__attr) {.strvalue=s});
2.16 - __store_via_object(__VALUE(attr), __size__, __INTVALUE(size));
2.17 - __store_via_object(__VALUE(attr), __key__, __NULL);
2.18 + __store_member(__VALUE(attr), __data__, (__attr) {.strvalue=s});
2.19 + __store_member(__VALUE(attr), __size__, __INTVALUE(size));
2.20 + __store_member(__VALUE(attr), __key__, __NULL);
2.21 return attr;
2.22 }
2.23
2.24 @@ -40,7 +40,7 @@
2.25 {
2.26 /* Create a new list and mutate the __data__ attribute. */
2.27 __attr attr = __NEWINSTANCE(__builtins___list_list);
2.28 - __store_via_object(__VALUE(attr), __data__, (__attr) {.seqvalue=f});
2.29 + __store_member(__VALUE(attr), __data__, (__attr) {.seqvalue=f});
2.30 return attr;
2.31 }
2.32
3.1 --- a/templates/native/float.c Mon Feb 04 18:53:56 2019 +0100
3.2 +++ b/templates/native/float.c Mon May 20 13:12:25 2019 +0200
3.3 @@ -63,6 +63,28 @@
3.4 return __NULL;
3.5 }
3.6
3.7 +static __attr make_result(__attr self, __attr other, double value)
3.8 +{
3.9 + __attr result;
3.10 +
3.11 + if (self.value->temporary)
3.12 + {
3.13 + __set_trailing_data(self, __builtins___float_float, value);
3.14 + return self;
3.15 + }
3.16 + else if (other.value->temporary)
3.17 + {
3.18 + __set_trailing_data(other, __builtins___float_float, value);
3.19 + return other;
3.20 + }
3.21 + else
3.22 + {
3.23 + result = __new_float(value);
3.24 + result.value->temporary = 1;
3.25 + return result;
3.26 + }
3.27 +}
3.28 +
3.29 /* Floating point operations. Exceptions are raised in the signal handler. */
3.30
3.31 __attr __fn_native_float_float_add(__attr __self, __attr self, __attr other)
3.32 @@ -70,7 +92,7 @@
3.33 /* self and other interpreted as float */
3.34 double i = __TOFLOAT(self);
3.35 double j = __TOFLOAT(other);
3.36 - return __new_float(i + j);
3.37 + return make_result(self, other, i + j);
3.38 }
3.39
3.40 __attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other)
3.41 @@ -78,7 +100,7 @@
3.42 /* self and other interpreted as float */
3.43 double i = __TOFLOAT(self);
3.44 double j = __TOFLOAT(other);
3.45 - return __new_float(i - j);
3.46 + return make_result(self, other, i - j);
3.47 }
3.48
3.49 __attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other)
3.50 @@ -86,7 +108,7 @@
3.51 /* self and other interpreted as float */
3.52 double i = __TOFLOAT(self);
3.53 double j = __TOFLOAT(other);
3.54 - return __new_float(i * j);
3.55 + return make_result(self, other, i * j);
3.56 }
3.57
3.58 __attr __fn_native_float_float_div(__attr __self, __attr self, __attr other)
3.59 @@ -94,7 +116,7 @@
3.60 /* self and other interpreted as float */
3.61 double i = __TOFLOAT(self);
3.62 double j = __TOFLOAT(other);
3.63 - return __new_float(i / j);
3.64 + return make_result(self, other, i / j);
3.65 }
3.66
3.67 __attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other)
3.68 @@ -102,7 +124,7 @@
3.69 /* self and other interpreted as float */
3.70 double i = __TOFLOAT(self);
3.71 double j = __TOFLOAT(other);
3.72 - return __new_float(fmod(i, j));
3.73 + return make_result(self, other, fmod(i, j));
3.74 }
3.75
3.76 __attr __fn_native_float_float_neg(__attr __self, __attr self)
3.77 @@ -128,7 +150,7 @@
3.78 __raise_overflow_error();
3.79
3.80 /* Return the result. */
3.81 - return __new_float(result);
3.82 + return make_result(self, other, result);
3.83 }
3.84
3.85 __attr __fn_native_float_float_le(__attr __self, __attr self, __attr other)
4.1 --- a/templates/native/list.c Mon Feb 04 18:53:56 2019 +0100
4.2 +++ b/templates/native/list.c Mon May 20 13:12:25 2019 +0200
4.3 @@ -1,6 +1,6 @@
4.4 /* Native functions for list operations.
4.5
4.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
4.7 +Copyright (C) 2016, 2017, 2019 Paul Boddie <paul@boddie.org.uk>
4.8
4.9 This program is free software; you can redistribute it and/or modify it under
4.10 the terms of the GNU General Public License as published by the Free Software
4.11 @@ -56,7 +56,7 @@
4.12
4.13 /* Replace the __data__ attribute if appropriate. */
4.14 if (newdata != data)
4.15 - __store_via_object(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata}));
4.16 + __store_member(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata}));
4.17 return __builtins___none_None;
4.18 }
4.19
4.20 @@ -84,7 +84,7 @@
4.21
4.22 /* Replace the __data__ attribute if appropriate. */
4.23 if (newdata != data)
4.24 - __store_via_object(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata}));
4.25 + __store_member(__VALUE(self), __data__, ((__attr) {.seqvalue=newdata}));
4.26 return __builtins___none_None;
4.27 }
4.28
5.1 --- a/templates/ops.c Mon Feb 04 18:53:56 2019 +0100
5.2 +++ b/templates/ops.c Mon May 20 13:12:25 2019 +0200
5.3 @@ -79,12 +79,31 @@
5.4
5.5 /* Direct storage operations. */
5.6
5.7 -int __store_via_object__(__ref obj, int pos, __attr value)
5.8 +__attr __store_attr__(__attr value)
5.9 +{
5.10 + if (!__ISNULL(value) && !__INTEGER(value) && value.value->temporary)
5.11 + value.value->temporary = 0;
5.12 +
5.13 + return value;
5.14 +}
5.15 +
5.16 +int __store_member__(__ref obj, int pos, __attr value)
5.17 {
5.18 obj->attrs[pos] = value;
5.19 return 1;
5.20 }
5.21
5.22 +int __store_via_object__(__ref obj, int pos, __attr value)
5.23 +{
5.24 + /* NOTE: To be tested at compile-time, with dynamic attribute access
5.25 + forbidding special attributes. */
5.26 +
5.27 + if ((pos != __ATTRPOS(__data__)) && (pos != __ATTRPOS(__key__)))
5.28 + __store_attr__(value);
5.29 +
5.30 + return __store_member__(obj, pos, value);
5.31 +}
5.32 +
5.33 int __store_via_class__(__ref obj, int pos, __attr value)
5.34 {
5.35 return __store_via_object__(__get_class(obj), pos, value);
6.1 --- a/templates/ops.h Mon Feb 04 18:53:56 2019 +0100
6.2 +++ b/templates/ops.h Mon May 20 13:12:25 2019 +0200
6.3 @@ -1,6 +1,6 @@
6.4 /* Common operations.
6.5
6.6 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
6.7 +Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
6.8
6.9 This program is free software; you can redistribute it and/or modify it under
6.10 the terms of the GNU General Public License as published by the Free Software
6.11 @@ -42,8 +42,18 @@
6.12 #define __load_via_object(OBJ, ATTRNAME) (__load_via_object__(OBJ, __ATTRPOS(ATTRNAME)))
6.13 #define __get_class_and_load(OBJ, ATTRNAME) (__get_class_and_load__(OBJ, __ATTRPOS(ATTRNAME)))
6.14
6.15 +/* Object state updating when assigning. */
6.16 +
6.17 +__attr __store_attr__(__attr value);
6.18 +
6.19 /* Direct storage operations. */
6.20
6.21 +int __store_member__(__ref obj, int pos, __attr value);
6.22 +
6.23 +#define __store_local(NAME, VALUE) (NAME = __store_attr__(VALUE))
6.24 +/* #define __store_local(NAME, VALUE) (NAME = VALUE) */
6.25 +#define __store_member(OBJ, ATTRNAME, VALUE) (__store_member__(OBJ, __ATTRPOS(ATTRNAME), VALUE))
6.26 +
6.27 int __store_via_class__(__ref obj, int pos, __attr value);
6.28 int __store_via_object__(__ref obj, int pos, __attr value);
6.29 int __get_class_and_store__(__ref obj, int pos, __attr value);
7.1 --- a/templates/progops.c Mon Feb 04 18:53:56 2019 +0100
7.2 +++ b/templates/progops.c Mon May 20 13:12:25 2019 +0200
7.3 @@ -32,7 +32,8 @@
7.4 {
7.5 obj->table = table;
7.6 obj->pos = __INSTANCEPOS;
7.7 - __store_via_object(obj, __class__, __ATTRVALUE(cls));
7.8 + obj->temporary = 0;
7.9 + __store_member(obj, __class__, __ATTRVALUE(cls));
7.10 }
7.11
7.12 __attr __new(const __table * table, __ref cls, size_t size, int immutable)
7.13 @@ -81,7 +82,7 @@
7.14
7.15 /* Store a reference to the data in the object's __data__ attribute. */
7.16
7.17 - __store_via_object(__VALUE(self), __data__, (__attr) {.seqvalue=data});
7.18 + __store_member(__VALUE(self), __data__, (__attr) {.seqvalue=data});
7.19 __newdata_sequence(number, data, args);
7.20 return self;
7.21 }
7.22 @@ -97,7 +98,7 @@
7.23
7.24 /* Store a reference to the data in the object's __data__ attribute. */
7.25
7.26 - __store_via_object(__VALUE(self), __data__, (__attr) {.seqvalue=data});
7.27 + __store_member(__VALUE(self), __data__, (__attr) {.seqvalue=data});
7.28 __newdata_sequence(number, data, args);
7.29 return self;
7.30 }
8.1 --- a/templates/types.h Mon Feb 04 18:53:56 2019 +0100
8.2 +++ b/templates/types.h Mon May 20 13:12:25 2019 +0200
8.3 @@ -94,6 +94,7 @@
8.4 {
8.5 const __table * table; /* attribute table */
8.6 __ppos pos; /* position of attribute indicating class */
8.7 + int temporary; /* temporary state of the object */
8.8 __attr attrs[]; /* attributes */
8.9
8.10 /* Specialisations of this type may add other members.
9.1 --- a/transresults.py Mon Feb 04 18:53:56 2019 +0100
9.2 +++ b/transresults.py Mon May 20 13:12:25 2019 +0200
9.3 @@ -114,7 +114,7 @@
9.4 # All other assignments involve the names as they were given.
9.5
9.6 else:
9.7 - return "%s = %s" % (attrname, self.expr)
9.8 + return "__store_local(%s, %s)" % (attrname, self.expr)
9.9
9.10 # Expressions.
9.11