comparison libinterp/octave-value/ov-classdef.cc @ 20595:c1a6c31ac29a

eliminate more simple uses of error_state * ov-classdef.cc: Eliminate simple uses of error_state.
author John W. Eaton <jwe@octave.org>
date Tue, 06 Oct 2015 00:20:02 -0400
parents dd6345fd8a97
children 729a85dafba8
comparison
equal deleted inserted replaced
20594:a05a0432dff4 20595:c1a6c31ac29a
98 make_function_of_class (const std::string& class_name, 98 make_function_of_class (const std::string& class_name,
99 const octave_value& fcn) 99 const octave_value& fcn)
100 { 100 {
101 octave_function *of = fcn.function_value (); 101 octave_function *of = fcn.function_value ();
102 102
103 if (! error_state) 103 of->stash_dispatch_class (class_name);
104 { 104
105 of->stash_dispatch_class (class_name); 105 octave_user_function *uf = of->user_function_value (true);
106 106
107 octave_user_function *uf = of->user_function_value (true); 107 if (uf)
108 108 {
109 if (! error_state && uf) 109 if (get_base_name (class_name) == uf->name ())
110 { 110 {
111 if (get_base_name (class_name) == uf->name ()) 111 uf->mark_as_class_constructor ();
112 { 112 uf->mark_as_classdef_constructor ();
113 uf->mark_as_class_constructor (); 113 }
114 uf->mark_as_classdef_constructor (); 114 else
115 } 115 uf->mark_as_class_method ();
116 else
117 uf->mark_as_class_method ();
118 }
119 } 116 }
120 } 117 }
121 118
122 static void 119 static void
123 make_function_of_class (const cdef_class& cls, const octave_value& fcn) 120 make_function_of_class (const cdef_class& cls, const octave_value& fcn)
180 return lookup_class (ov.string_value ()); 177 return lookup_class (ov.string_value ());
181 else 178 else
182 { 179 {
183 cdef_class cls (to_cdef (ov)); 180 cdef_class cls (to_cdef (ov));
184 181
185 if (! error_state) 182 return lookup_class (cls);
186 return lookup_class (cls);
187 } 183 }
188 184
189 return cdef_class (); 185 return cdef_class ();
190 } 186 }
191 187
233 retval = true; 229 retval = true;
234 else if (max_depth != 0) 230 else if (max_depth != 0)
235 { 231 {
236 Cell c = clsb.get ("SuperClasses").cell_value (); 232 Cell c = clsb.get ("SuperClasses").cell_value ();
237 233
238 for (int i = 0; ! error_state && ! retval && i < c.numel (); i++) 234 for (int i = 0; ! retval && i < c.numel (); i++)
239 { 235 {
240 cdef_class cls = lookup_class (c(i)); 236 cdef_class cls = lookup_class (c(i));
241 237
242 if (! error_state) 238 retval = is_superclass (clsa, cls, true,
243 retval = is_superclass (clsa, cls, true, 239 max_depth < 0 ? max_depth : max_depth-1);
244 max_depth < 0 ? max_depth : max_depth-1);
245 } 240 }
246 } 241 }
247 242
248 return retval; 243 return retval;
249 } 244 }
285 || fcn->is_anonymous_function_of_class () 280 || fcn->is_anonymous_function_of_class ()
286 || (fcn->is_private_function () 281 || (fcn->is_private_function ()
287 && ! fcn->dispatch_class ().empty ()))) 282 && ! fcn->dispatch_class ().empty ())))
288 { 283 {
289 cls = lookup_class (fcn->dispatch_class ()); 284 cls = lookup_class (fcn->dispatch_class ());
290 if (! error_state) 285
291 { 286 name = fcn->name ();
292 name = fcn->name (); 287 in_constructor = fcn->is_classdef_constructor ();
293 in_constructor = fcn->is_classdef_constructor ();
294 }
295 } 288 }
296 289
297 return cls; 290 return cls;
298 } 291 }
299 292
330 cdef_class ctx = get_class_context (); 323 cdef_class ctx = get_class_context ();
331 324
332 // The access is private or protected, this requires a 325 // The access is private or protected, this requires a
333 // valid class context. 326 // valid class context.
334 327
335 if (! error_state && ctx.ok ()) 328 if (ctx.ok ())
336 { 329 {
337 if (acc_s == "private") 330 if (acc_s == "private")
338 return (ctx == cls); 331 return (ctx == cls);
339 else if (acc_s == "protected") 332 else if (acc_s == "protected")
340 { 333 {
388 381
389 cdef_class ctx = get_class_context (); 382 cdef_class ctx = get_class_context ();
390 383
391 // At this point, a class context is always required. 384 // At this point, a class context is always required.
392 385
393 if (! error_state && ctx.ok ()) 386 if (ctx.ok ())
394 { 387 {
395 if (ctx == cls) 388 if (ctx == cls)
396 return true; 389 return true;
397 390
398 for (int i = 0; ! error_state && i < acc.numel (); i++) 391 for (int i = 0; i < acc.numel (); i++)
399 { 392 {
400 cdef_class acc_cls (to_cdef (acc_c(i))); 393 cdef_class acc_cls (to_cdef (acc_c(i)));
401 394
402 if (! error_state) 395 if (is_superclass (acc_cls, ctx))
403 { 396 return true;
404 if (is_superclass (acc_cls, ctx))
405 return true;
406 }
407 } 397 }
408 } 398 }
409 } 399 }
410 else 400 else
411 error ("invalid property/method access in class `%s'", 401 error ("invalid property/method access in class `%s'",
581 error ("fevalStatic: method not found: %s", meth_name.c_str ()); 571 error ("fevalStatic: method not found: %s", meth_name.c_str ());
582 } 572 }
583 else 573 else
584 error ("fevalStatic: invalid method name, expected a string value"); 574 error ("fevalStatic: invalid method name, expected a string value");
585 } 575 }
586 error ("fevalStatic: invalid object, expected a meta.class object"); 576 else
577 error ("fevalStatic: invalid object, expected a meta.class object");
587 } 578 }
588 else 579 else
589 error ("fevalStatic: invalid arguments"); 580 error ("fevalStatic: invalid arguments");
590 581
591 return retval; 582 return retval;
747 if (has_handle_class) 738 if (has_handle_class)
748 cls.mark_as_handle_class (); 739 cls.mark_as_handle_class ();
749 } 740 }
750 } 741 }
751 742
752 if (error_state)
753 return cdef_class ();
754
755 if (! name.empty ()) 743 if (! name.empty ())
756 cdef_manager::register_class (cls); 744 cdef_manager::register_class (cls);
757 745
758 return cls; 746 return cls;
759 } 747 }
907 { 895 {
908 octave_value_list args; 896 octave_value_list args;
909 897
910 args(1) = make_idx_args (type, idx, "subsref"); 898 args(1) = make_idx_args (type, idx, "subsref");
911 899
912 if (! error_state) 900 count++;
913 { 901 args(0) = octave_value (this);
914 count++; 902
915 args(0) = octave_value (this); 903 retval = meth.execute (args, nargout, true, "subsref");
916
917 retval = meth.execute (args, nargout, true, "subsref");
918 }
919 904
920 return retval; 905 return retval;
921 } 906 }
922 } 907 }
923 908
924 // At this point, the default subsref mechanism must be used. 909 // At this point, the default subsref mechanism must be used.
925 910
926 retval = object.subsref (type, idx, nargout, skip, cdef_class ()); 911 retval = object.subsref (type, idx, nargout, skip, cdef_class ());
927 912
928 if (! error_state) 913 if (type.length () > skip && idx.size () > skip)
929 { 914 retval = retval(0).next_subsref (nargout, type, idx, skip);
930 if (type.length () > skip && idx.size () > skip)
931 retval = retval(0).next_subsref (nargout, type, idx, skip);
932 }
933 915
934 return retval; 916 return retval;
935 } 917 }
936 918
937 octave_value 919 octave_value
947 // purpose (not sure we should even implement this) and any overload subsref 929 // purpose (not sure we should even implement this) and any overload subsref
948 // should not be called. 930 // should not be called.
949 931
950 retval = object.subsref (type, idx, 1, skip, cdef_class (), auto_add); 932 retval = object.subsref (type, idx, 1, skip, cdef_class (), auto_add);
951 933
952 if (! error_state) 934 if (type.length () > skip && idx.size () > skip)
953 { 935 retval = retval(0).next_subsref (1, type, idx, skip);
954 if (type.length () > skip && idx.size () > skip)
955 retval = retval(0).next_subsref (1, type, idx, skip);
956 }
957 936
958 return retval.length () > 0 ? retval(0) : octave_value (); 937 return retval.length () > 0 ? retval(0) : octave_value ();
959 } 938 }
960 939
961 octave_value 940 octave_value
975 { 954 {
976 octave_value_list args; 955 octave_value_list args;
977 956
978 args(1) = make_idx_args (type, idx, "subsasgn"); 957 args(1) = make_idx_args (type, idx, "subsasgn");
979 958
980 if (! error_state) 959 count++;
981 { 960 args(0) = octave_value (this);
982 count++; 961 args(2) = rhs;
983 args(0) = octave_value (this); 962
984 args(2) = rhs; 963 octave_value_list retlist;
985 964
986 octave_value_list retlist; 965 retlist = meth.execute (args, 1, true, "subsasgn");
987 966
988 retlist = meth.execute (args, 1, true, "subsasgn"); 967 if (retlist.length () > 0)
989 968 retval = retlist(0);
990 if (! error_state) 969 else
991 { 970 error ("overloaded method `subsasgn' did not return any value");
992 if (retlist.length () > 0) 971 }
993 retval = retlist(0); 972 }
994 else 973
995 error ("overloaded method `subsasgn' did not return any value"); 974 if (! retval.is_defined ())
996 }
997 }
998 }
999 }
1000
1001 if (! error_state && ! retval.is_defined ())
1002 retval = object.subsasgn (type, idx, rhs); 975 retval = object.subsasgn (type, idx, rhs);
1003 976
1004 return retval; 977 return retval;
1005 } 978 }
1006 979
1011 { 984 {
1012 if (type.length () == 1 && type[0] == '(') 985 if (type.length () == 1 && type[0] == '(')
1013 { 986 {
1014 object = object.make_array (); 987 object = object.make_array ();
1015 988
1016 if (! error_state) 989 return subsasgn (type, idx, rhs);
1017 return subsasgn (type, idx, rhs);
1018 } 990 }
1019 else 991 else
1020 return octave_base_value::undef_subsasgn (type, idx, rhs); 992 return octave_base_value::undef_subsasgn (type, idx, rhs);
1021 993
1022 return octave_value (); 994 return octave_value ();
1199 default: 1171 default:
1200 retval = do_multi_index_op (1, octave_value_list ()); 1172 retval = do_multi_index_op (1, octave_value_list ());
1201 break; 1173 break;
1202 } 1174 }
1203 1175
1204 if (! error_state) 1176 if (type.length () > skip && idx.size () > skip
1205 { 1177 && retval.length () > 0)
1206 if (type.length () > skip && idx.size () > skip 1178 retval = retval(0).next_subsref (nargout, type, idx, skip);
1207 && retval.length () > 0)
1208 retval = retval(0).next_subsref (nargout, type, idx, skip);
1209 }
1210 1179
1211 return retval; 1180 return retval;
1212 } 1181 }
1213 1182
1214 octave_value 1183 octave_value
1238 std::string mname = args(0).string_value (); 1207 std::string mname = args(0).string_value ();
1239 std::string cname = args(1).string_value (); 1208 std::string cname = args(1).string_value ();
1240 1209
1241 cdef_class cls = lookup_class (cname); 1210 cdef_class cls = lookup_class (cname);
1242 1211
1243 if (! error_state) 1212 if (in_constructor)
1244 { 1213 {
1245 if (in_constructor) 1214 if (is_direct_superclass (cls, ctx))
1246 { 1215 {
1247 if (is_direct_superclass (cls, ctx)) 1216 if (is_constructed_object (mname))
1248 { 1217 {
1249 if (is_constructed_object (mname)) 1218 octave_value sym = symbol_table::varval (mname);
1250 { 1219
1251 octave_value sym = symbol_table::varval (mname); 1220 cls.run_constructor (to_cdef_ref (sym), idx);
1252 1221
1253 cls.run_constructor (to_cdef_ref (sym), idx); 1222 retval(0) = sym;
1254
1255 retval(0) = sym;
1256 }
1257 else
1258 error ("cannot call superclass constructor with "
1259 "variable `%s'", mname.c_str ());
1260 } 1223 }
1261 else 1224 else
1262 error ("`%s' is not a direct superclass of `%s'", 1225 error ("cannot call superclass constructor with "
1226 "variable `%s'", mname.c_str ());
1227 }
1228 else
1229 error ("`%s' is not a direct superclass of `%s'",
1230 cname.c_str (), ctx.get_name ().c_str ());
1231 }
1232 else
1233 {
1234 if (mname == meth_name)
1235 {
1236 if (is_strict_superclass (cls, ctx))
1237 {
1238 // I see 2 possible implementations here:
1239 // 1) use cdef_object::subsref with a different class
1240 // context; this avoids duplicating code, but
1241 // assumes the object is always the first argument
1242 // 2) lookup the method manually and call
1243 // cdef_method::execute; this duplicates part of
1244 // logic in cdef_object::subsref, but avoid the
1245 // assumption of 1)
1246 // Not being sure about the assumption of 1), I
1247 // go with option 2) for the time being.
1248
1249 cdef_method meth = cls.find_method (meth_name, false);
1250
1251 if (meth.ok ())
1252 retval = meth.execute (idx, nargout, true,
1253 meth_name);
1254 else
1255 error ("no method `%s' found in superclass `%s'",
1256 meth_name.c_str (), cname.c_str ());
1257 }
1258 else
1259 error ("`%s' is not a superclass of `%s'",
1263 cname.c_str (), ctx.get_name ().c_str ()); 1260 cname.c_str (), ctx.get_name ().c_str ());
1264 } 1261 }
1265 else 1262 else
1266 { 1263 error ("method name mismatch (`%s' != `%s')",
1267 if (mname == meth_name) 1264 mname.c_str (), meth_name.c_str ());
1268 {
1269 if (is_strict_superclass (cls, ctx))
1270 {
1271 // I see 2 possible implementations here:
1272 // 1) use cdef_object::subsref with a different class
1273 // context; this avoids duplicating code, but
1274 // assumes the object is always the first argument
1275 // 2) lookup the method manually and call
1276 // cdef_method::execute; this duplicates part of
1277 // logic in cdef_object::subsref, but avoid the
1278 // assumption of 1)
1279 // Not being sure about the assumption of 1), I
1280 // go with option 2) for the time being.
1281
1282 cdef_method meth = cls.find_method (meth_name, false);
1283
1284 if (meth.ok ())
1285 retval = meth.execute (idx, nargout, true,
1286 meth_name);
1287 else
1288 error ("no method `%s' found in superclass `%s'",
1289 meth_name.c_str (), cname.c_str ());
1290 }
1291 else
1292 error ("`%s' is not a superclass of `%s'",
1293 cname.c_str (), ctx.get_name ().c_str ());
1294 }
1295 else
1296 error ("method name mismatch (`%s' != `%s')",
1297 mname.c_str (), meth_name.c_str ());
1298 }
1299 } 1265 }
1300 } 1266 }
1301 else if (! error_state) 1267 else if (! error_state)
1302 error ("superclass calls can only occur in methods or constructors"); 1268 error ("superclass calls can only occur in methods or constructors");
1303 1269
1360 Array<cdef_object> a_obj = array_value (); 1326 Array<cdef_object> a_obj = array_value ();
1361 1327
1362 Cell cvalue (a_obj.dims ()); 1328 Cell cvalue (a_obj.dims ());
1363 1329
1364 for (octave_idx_type i = 0; i < a_obj.numel (); i++) 1330 for (octave_idx_type i = 0; i < a_obj.numel (); i++)
1365 { 1331 cvalue (i) = it->second.get_value (a_obj(i), false);
1366 cvalue (i) = it->second.get_value (a_obj(i), false); 1332
1367 1333 retval.setfield (it->first, cvalue);
1368 if (error_state)
1369 break;
1370 }
1371
1372 if (! error_state)
1373 retval.setfield (it->first, cvalue);
1374 } 1334 }
1375 else 1335 else
1376 { 1336 {
1377 Cell cvalue (dim_vector (1, 1), 1337 Cell cvalue (dim_vector (1, 1),
1378 it->second.get_value (*this, false)); 1338 it->second.get_value (*this, false));
1379 1339
1380 if (! error_state) 1340 retval.setfield (it->first, cvalue);
1381 retval.setfield (it->first, cvalue);
1382 } 1341 }
1383
1384 if (error_state)
1385 break;
1386 } 1342 }
1387 } 1343 }
1388 1344
1389 return retval; 1345 return retval;
1390 } 1346 }
1448 retval = meth.execute (cdef_object (this), args, _nargout, 1404 retval = meth.execute (cdef_object (this), args, _nargout,
1449 true, "subsref"); 1405 true, "subsref");
1450 } 1406 }
1451 } 1407 }
1452 1408
1453 if (skip == 0 && ! error_state) 1409 if (skip == 0)
1454 { 1410 {
1455 cdef_property prop = cls.find_property (name); 1411 cdef_property prop = cls.find_property (name);
1456 1412
1457 if (prop.ok ()) 1413 if (prop.ok ())
1458 { 1414 {
1519 { 1475 {
1520 case '.': 1476 case '.':
1521 { 1477 {
1522 std::string name = (idx.front ())(0).string_value (); 1478 std::string name = (idx.front ())(0).string_value ();
1523 1479
1524 if (! error_state) 1480 cdef_property prop = cls.find_property (name);
1481
1482 if (prop.ok ())
1525 { 1483 {
1526 cdef_property prop = cls.find_property (name); 1484 if (prop.is_constant ())
1527 1485 error ("subsasgn: cannot assign constant property: %s",
1528 if (prop.ok ()) 1486 name.c_str ());
1487 else
1529 { 1488 {
1530 if (prop.is_constant ()) 1489 refcount++;
1531 error ("subsasgn: cannot assign constant property: %s", 1490
1532 name.c_str ()); 1491 cdef_object obj (this);
1492
1493 if (type.length () == 1)
1494 {
1495 prop.set_value (obj, rhs, true, "subsasgn");
1496
1497 retval = to_ov (obj);
1498 }
1533 else 1499 else
1534 { 1500 {
1535 refcount++; 1501 octave_value val =
1536 1502 prop.get_value (obj, true, "subsasgn");
1537 cdef_object obj (this); 1503
1538 1504 std::list<octave_value_list> args (idx);
1539 if (type.length () == 1) 1505
1540 { 1506 args.erase (args.begin ());
1541 prop.set_value (obj, rhs, true, "subsasgn"); 1507
1542 1508 val = val.assign (octave_value::op_asn_eq,
1543 if (! error_state) 1509 type.substr (1), args, rhs);
1544 retval = to_ov (obj); 1510
1545 } 1511 if (val.class_name () != "object"
1546 else 1512 || ! to_cdef (val).is_handle_object ())
1547 { 1513 prop.set_value (obj, val, true, "subsasgn");
1548 octave_value val = 1514
1549 prop.get_value (obj, true, "subsasgn"); 1515 retval = to_ov (obj);
1550
1551 if (! error_state)
1552 {
1553 std::list<octave_value_list> args (idx);
1554
1555 args.erase (args.begin ());
1556
1557 val = val.assign (octave_value::op_asn_eq,
1558 type.substr (1), args, rhs);
1559
1560 if (! error_state)
1561 {
1562 if (val.class_name () != "object"
1563 || ! to_cdef (val).is_handle_object ())
1564 prop.set_value (obj, val, true, "subsasgn");
1565
1566 if (! error_state)
1567 retval = to_ov (obj);
1568 }
1569 }
1570 }
1571 } 1516 }
1572 } 1517 }
1573 else
1574 error ("subsasgn: unknown property: %s", name.c_str ());
1575 } 1518 }
1519 else
1520 error ("subsasgn: unknown property: %s", name.c_str ());
1576 } 1521 }
1577 break; 1522 break;
1578 1523
1579 case '(': 1524 case '(':
1580 { 1525 {
1588 1533
1589 new_obj.set_class (get_class ()); 1534 new_obj.set_class (get_class ());
1590 1535
1591 octave_value tmp = new_obj.subsasgn (type, idx, rhs); 1536 octave_value tmp = new_obj.subsasgn (type, idx, rhs);
1592 1537
1593 if (! error_state) 1538 retval = tmp;
1594 retval = tmp;
1595 } 1539 }
1596 break; 1540 break;
1597 1541
1598 default: 1542 default:
1599 error ("subsasgn: object cannot be index with `%c'", type[0]); 1543 error ("subsasgn: object cannot be index with `%c'", type[0]);
1608 { 1552 {
1609 std::string cls_name = cls.get_name (); 1553 std::string cls_name = cls.get_name ();
1610 1554
1611 Cell supcls = cls.get ("SuperClasses").cell_value (); 1555 Cell supcls = cls.get ("SuperClasses").cell_value ();
1612 1556
1613 if (! error_state) 1557 std::list<cdef_class> supcls_list = lookup_classes (supcls);
1614 { 1558
1615 std::list<cdef_class> supcls_list = lookup_classes (supcls); 1559 ctor_list[cls] = supcls_list;
1616
1617 if (! error_state)
1618 ctor_list[cls] = supcls_list;
1619 }
1620 } 1560 }
1621 1561
1622 octave_value_list 1562 octave_value_list
1623 cdef_object_array::subsref (const std::string& type, 1563 cdef_object_array::subsref (const std::string& type,
1624 const std::list<octave_value_list>& idx, 1564 const std::list<octave_value_list>& idx,
1643 } 1583 }
1644 1584
1645 bool is_scalar = true; 1585 bool is_scalar = true;
1646 Array<idx_vector> iv (dim_vector (1, ival.length ())); 1586 Array<idx_vector> iv (dim_vector (1, ival.length ()));
1647 1587
1648 for (int i = 0; ! error_state && i < ival.length (); i++) 1588 for (int i = 0; i < ival.length (); i++)
1649 { 1589 {
1650 try 1590 try
1651 { 1591 {
1652 iv(i) = ival(i).index_vector (); 1592 iv(i) = ival(i).index_vector ();
1653 } 1593 }
1655 { 1595 {
1656 // Rethrow to allow more info to be reported later. 1596 // Rethrow to allow more info to be reported later.
1657 e.set_pos_if_unset (ival.length (), i+1); 1597 e.set_pos_if_unset (ival.length (), i+1);
1658 throw; 1598 throw;
1659 } 1599 }
1660 if (! error_state) 1600
1661 is_scalar = is_scalar && iv(i).is_scalar (); 1601 is_scalar = is_scalar && iv(i).is_scalar ();
1662 } 1602 }
1663 1603
1664 if (! error_state) 1604 Array<cdef_object> ires = array.index (iv, auto_add);
1605
1606 // If resizing is enabled (auto_add = true), it's possible
1607 // indexing was out-of-bound and the result array contains
1608 // invalid cdef_objects.
1609
1610 if (auto_add)
1611 fill_empty_values (ires);
1612
1613 if (is_scalar)
1614 retval(0) = to_ov (ires(0));
1615 else
1665 { 1616 {
1666 Array<cdef_object> ires = array.index (iv, auto_add); 1617 cdef_object array_obj (new cdef_object_array (ires));
1667 1618
1668 if (! error_state) 1619 array_obj.set_class (get_class ());
1669 { 1620
1670 // If resizing is enabled (auto_add = true), it's possible 1621 retval(0) = to_ov (array_obj);
1671 // indexing was out-of-bound and the result array contains
1672 // invalid cdef_objects.
1673
1674 if (auto_add)
1675 fill_empty_values (ires);
1676
1677 if (is_scalar)
1678 retval(0) = to_ov (ires(0));
1679 else
1680 {
1681 cdef_object array_obj (new cdef_object_array (ires));
1682
1683 array_obj.set_class (get_class ());
1684
1685 retval(0) = to_ov (array_obj);
1686 }
1687 }
1688 } 1622 }
1689 } 1623 }
1690 break; 1624 break;
1691 1625
1692 case '.': 1626 case '.':
1703 for (octave_idx_type i = 0; i < n; i++) 1637 for (octave_idx_type i = 0; i < n; i++)
1704 { 1638 {
1705 octave_value_list r = array(i).subsref (type, idx, 1, dummy_skip, 1639 octave_value_list r = array(i).subsref (type, idx, 1, dummy_skip,
1706 dummy_cls); 1640 dummy_cls);
1707 1641
1708 if (! error_state) 1642 if (r.length () > 0)
1709 { 1643 c(i) = r(0);
1710 if (r.length () > 0)
1711 c(i) = r(0);
1712 }
1713 else
1714 break;
1715 } 1644 }
1716 1645
1717 if (! error_state) 1646 retval(0) = octave_value (c, true);
1718 retval(0) = octave_value (c, true);
1719 1647
1720 break; 1648 break;
1721 } 1649 }
1722 // fall through "default" 1650 // fall through "default"
1723 1651
1742 case '(': 1670 case '(':
1743 if (type.length () == 1) 1671 if (type.length () == 1)
1744 { 1672 {
1745 cdef_object rhs_obj = to_cdef (rhs); 1673 cdef_object rhs_obj = to_cdef (rhs);
1746 1674
1747 if (! error_state) 1675 if (rhs_obj.get_class () == get_class ())
1748 { 1676 {
1749 if (rhs_obj.get_class () == get_class ()) 1677 const octave_value_list& ival = idx.front ();
1678 bool is_scalar = true;
1679 Array<idx_vector> iv (dim_vector (1, ival.length ()));
1680
1681 for (int i = 0; i < ival.length (); i++)
1750 { 1682 {
1751 const octave_value_list& ival = idx.front (); 1683 try
1752 bool is_scalar = true;
1753 Array<idx_vector> iv (dim_vector (1, ival.length ()));
1754
1755 for (int i = 0; ! error_state && i < ival.length (); i++)
1756 { 1684 {
1757 try 1685 iv(i) = ival(i).index_vector ();
1758 {
1759 iv(i) = ival(i).index_vector ();
1760 }
1761 catch (index_exception& e)
1762 {
1763 e.set_pos_if_unset (ival.length (), i+1);
1764 throw; // var name set in pt-idx.cc / pt-assign.cc
1765 }
1766 if (! error_state)
1767 is_scalar = is_scalar && iv(i).is_scalar ();
1768 } 1686 }
1769 1687 catch (index_exception& e)
1770 if (! error_state)
1771 { 1688 {
1772 Array<cdef_object> rhs_mat; 1689 e.set_pos_if_unset (ival.length (), i+1);
1773 1690 throw; // var name set in pt-idx.cc / pt-assign.cc
1774 if (! rhs_obj.is_array ())
1775 {
1776 rhs_mat = Array<cdef_object> (dim_vector (1, 1));
1777 rhs_mat(0) = rhs_obj;
1778 }
1779 else
1780 rhs_mat = rhs_obj.array_value ();
1781
1782 if (! error_state)
1783 {
1784 octave_idx_type n = array.numel ();
1785
1786 array.assign (iv, rhs_mat, cdef_object ());
1787
1788 if (! error_state)
1789 {
1790 if (array.numel () > n)
1791 fill_empty_values ();
1792
1793 if (! error_state)
1794 {
1795 refcount++;
1796 retval = to_ov (cdef_object (this));
1797 }
1798 }
1799 }
1800 } 1691 }
1692
1693 is_scalar = is_scalar && iv(i).is_scalar ();
1694 }
1695
1696 Array<cdef_object> rhs_mat;
1697
1698 if (! rhs_obj.is_array ())
1699 {
1700 rhs_mat = Array<cdef_object> (dim_vector (1, 1));
1701 rhs_mat(0) = rhs_obj;
1801 } 1702 }
1802 else 1703 else
1803 error ("can't assign %s object into array of %s objects.", 1704 rhs_mat = rhs_obj.array_value ();
1804 rhs_obj.class_name ().c_str (), 1705
1805 class_name ().c_str ()); 1706 octave_idx_type n = array.numel ();
1707
1708 array.assign (iv, rhs_mat, cdef_object ());
1709
1710 if (array.numel () > n)
1711 fill_empty_values ();
1712
1713 refcount++;
1714 retval = to_ov (cdef_object (this));
1806 } 1715 }
1716 else
1717 error ("can't assign %s object into array of %s objects.",
1718 rhs_obj.class_name ().c_str (),
1719 class_name ().c_str ());
1807 } 1720 }
1808 else 1721 else
1809 { 1722 {
1810 const octave_value_list& ival = idx.front (); 1723 const octave_value_list& ival = idx.front ();
1811 1724
1812 bool is_scalar = true; 1725 bool is_scalar = true;
1813 1726
1814 Array<idx_vector> iv (dim_vector (1, ival.length ())); 1727 Array<idx_vector> iv (dim_vector (1, ival.length ()));
1815 1728
1816 for (int i = 0; ! error_state && i < ival.length (); i++) 1729 for (int i = 0; i < ival.length (); i++)
1817 { 1730 {
1818 try 1731 try
1819 { 1732 {
1820 iv(i) = ival(i).index_vector (); 1733 iv(i) = ival(i).index_vector ();
1821 } 1734 }
1824 // Rethrow to allow more info to be reported later. 1737 // Rethrow to allow more info to be reported later.
1825 e.set_pos_if_unset (ival.length (), i+1); 1738 e.set_pos_if_unset (ival.length (), i+1);
1826 throw; 1739 throw;
1827 } 1740 }
1828 1741
1829 if (! error_state) 1742 is_scalar = is_scalar && iv(i).is_scalar ();
1743
1744 if (! is_scalar)
1745 error ("subsasgn: invalid indexing for object array "
1746 "assignment, the index must reference a single "
1747 "object in the array.");
1748 }
1749
1750 Array<cdef_object> a = array.index (iv, true);
1751
1752 if (a.numel () != 1)
1753 error ("subsasgn: invalid indexing for object array "
1754 "assignment");
1755
1756 cdef_object obj = a(0);
1757
1758 int ignore_copies = 0;
1759
1760 // If the object in 'a' is not valid, this means the index
1761 // was out-of-bound and we need to create a new object.
1762
1763 if (! obj.ok ())
1764 obj = get_class ().construct_object (octave_value_list ());
1765 else
1766 // Optimize the subsasgn call to come. There are 2 copies
1767 // that we can safely ignore:
1768 // - 1 in "array"
1769 // - 1 in "a"
1770 ignore_copies = 2;
1771
1772 std::list<octave_value_list> next_idx (idx);
1773
1774 next_idx.erase (next_idx.begin ());
1775
1776 octave_value tmp = obj.subsasgn (type.substr (1), next_idx,
1777 rhs, ignore_copies);
1778
1779 cdef_object robj = to_cdef (tmp);
1780
1781 if (robj.ok ()
1782 && ! robj.is_array ()
1783 && robj.get_class () == get_class ())
1784 {
1785 // Small optimization, when dealing with handle
1786 // objects, we don't need to re-assign the result
1787 // of subsasgn back into the array.
1788
1789 if (! robj.is (a(0)))
1830 { 1790 {
1831 is_scalar = is_scalar && iv(i).is_scalar (); 1791 Array<cdef_object> rhs_a (dim_vector (1, 1),
1832 1792 robj);
1833 if (! is_scalar) 1793
1834 error ("subsasgn: invalid indexing for object array " 1794 octave_idx_type n = array.numel ();
1835 "assignment, the index must reference a single " 1795
1836 "object in the array."); 1796 array.assign (iv, rhs_a);
1797
1798 if (array.numel () > n)
1799 fill_empty_values ();
1837 } 1800 }
1801
1802 refcount++;
1803
1804 retval = to_ov (cdef_object (this));
1838 } 1805 }
1839 1806 else
1840 if (! error_state) 1807 error ("subasgn: invalid assignment into array of %s "
1841 { 1808 "objects", class_name ().c_str ());
1842 Array<cdef_object> a = array.index (iv, true);
1843
1844 if (a.numel () != 1)
1845 error ("subsasgn: invalid indexing for object array "
1846 "assignment");
1847
1848 if (! error_state)
1849 {
1850 cdef_object obj = a(0);
1851
1852 int ignore_copies = 0;
1853
1854 // If the object in 'a' is not valid, this means the index
1855 // was out-of-bound and we need to create a new object.
1856
1857 if (! obj.ok ())
1858 obj = get_class ().construct_object (octave_value_list ());
1859 else
1860 // Optimize the subsasgn call to come. There are 2 copies
1861 // that we can safely ignore:
1862 // - 1 in "array"
1863 // - 1 in "a"
1864 ignore_copies = 2;
1865
1866 std::list<octave_value_list> next_idx (idx);
1867
1868 next_idx.erase (next_idx.begin ());
1869
1870 octave_value tmp = obj.subsasgn (type.substr (1), next_idx,
1871 rhs, ignore_copies);
1872
1873 if (! error_state)
1874 {
1875 cdef_object robj = to_cdef (tmp);
1876
1877 if (robj.ok ()
1878 && ! robj.is_array ()
1879 && robj.get_class () == get_class ())
1880 {
1881 // Small optimization, when dealing with handle
1882 // objects, we don't need to re-assign the result
1883 // of subsasgn back into the array.
1884
1885 if (! robj.is (a(0)))
1886 {
1887 Array<cdef_object> rhs_a (dim_vector (1, 1),
1888 robj);
1889
1890 octave_idx_type n = array.numel ();
1891
1892 array.assign (iv, rhs_a);
1893
1894 if (array.numel () > n)
1895 fill_empty_values ();
1896 }
1897
1898 refcount++;
1899
1900 retval = to_ov (cdef_object (this));
1901 }
1902 else
1903 error ("subasgn: invalid assignment into array of %s "
1904 "objects", class_name ().c_str ());
1905 }
1906 }
1907 }
1908 } 1809 }
1909 break; 1810 break;
1910 1811
1911 default: 1812 default:
1912 error ("can't perform indexing operation on array of %s objects", 1813 error ("can't perform indexing operation on array of %s objects",
1920 void 1821 void
1921 cdef_object_array::fill_empty_values (Array<cdef_object>& arr) 1822 cdef_object_array::fill_empty_values (Array<cdef_object>& arr)
1922 { 1823 {
1923 cdef_class cls = get_class (); 1824 cdef_class cls = get_class ();
1924 1825
1925 if (! error_state) 1826 cdef_object obj;
1926 { 1827
1927 cdef_object obj; 1828 int n = arr.numel ();
1928 1829
1929 int n = arr.numel (); 1830 for (int i = 0; i < n; i++)
1930 1831 {
1931 for (int i = 0; ! error_state && i < n; i++) 1832 if (! arr.xelem (i).ok ())
1932 { 1833 {
1933 if (! arr.xelem (i).ok ()) 1834 if (! obj.ok ())
1934 { 1835 {
1935 if (! obj.ok ()) 1836 obj = cls.construct_object (octave_value_list ());
1936 { 1837
1937 obj = cls.construct_object (octave_value_list ()); 1838 arr.xelem (i) = obj;
1938
1939 if (! error_state)
1940 arr.xelem (i) = obj;
1941 }
1942 else
1943 arr.xelem (i) = obj.copy ();
1944 } 1839 }
1840 else
1841 arr.xelem (i) = obj.copy ();
1945 } 1842 }
1946 } 1843 }
1947 } 1844 }
1948 1845
1949 bool 1846 bool
2030 1927
2031 for (int i = 0; i < super_classes.numel (); i++) 1928 for (int i = 0; i < super_classes.numel (); i++)
2032 { 1929 {
2033 cdef_class cls = lookup_class (super_classes(i)); 1930 cdef_class cls = lookup_class (super_classes(i));
2034 1931
2035 if (! error_state) 1932 cdef_method meth = cls.find_method (nm);
2036 { 1933
2037 cdef_method meth = cls.find_method (nm); 1934 if (meth.ok ())
2038 1935 return meth;
2039 if (meth.ok ())
2040 return meth;
2041 }
2042 } 1936 }
2043 } 1937 }
2044 1938
2045 return cdef_method (); 1939 return cdef_method ();
2046 } 1940 }
2052 : tree_walker (), who (ctor), obj_name (obj) { } 1946 : tree_walker (), who (ctor), obj_name (obj) { }
2053 1947
2054 void visit_statement_list (tree_statement_list& t) 1948 void visit_statement_list (tree_statement_list& t)
2055 { 1949 {
2056 for (tree_statement_list::const_iterator it = t.begin (); 1950 for (tree_statement_list::const_iterator it = t.begin ();
2057 ! error_state && it != t.end (); ++it) 1951 it != t.end (); ++it)
2058 (*it)->accept (*this); 1952 (*it)->accept (*this);
2059 } 1953 }
2060 1954
2061 void visit_statement (tree_statement& t) 1955 void visit_statement (tree_statement& t)
2062 { 1956 {
2186 { 2080 {
2187 std::string obj_name = ret_list->front ()->name (); 2081 std::string obj_name = ret_list->front ()->name ();
2188 ctor_analyzer a (meth.get_name (), obj_name); 2082 ctor_analyzer a (meth.get_name (), obj_name);
2189 2083
2190 body->accept (a); 2084 body->accept (a);
2191 if (! error_state) 2085
2086 std::list<cdef_class> explicit_ctor_list
2087 = a.get_constructor_list ();
2088
2089 for (std::list<cdef_class>::const_iterator
2090 it = explicit_ctor_list.begin ();
2091 it != explicit_ctor_list.end ();
2092 ++it)
2192 { 2093 {
2193 std::list<cdef_class> explicit_ctor_list
2194 = a.get_constructor_list ();
2195
2196 for (std::list<cdef_class>::const_iterator
2197 it = explicit_ctor_list.begin ();
2198 ! error_state && it != explicit_ctor_list.end ();
2199 ++it)
2200 {
2201 #if DEBUG_TRACE 2094 #if DEBUG_TRACE
2202 std::cerr << "explicit superclass constructor: " 2095 std::cerr << "explicit superclass constructor: "
2203 << it->get_name () << std::endl; 2096 << it->get_name () << std::endl;
2204 #endif 2097 #endif
2205 2098
2206 implicit_ctor_list.remove (*it); 2099 implicit_ctor_list.remove (*it);
2207 }
2208 } 2100 }
2209 } 2101 }
2210 else 2102 else
2211 error ("%s: invalid constructor output arguments", 2103 error ("%s: invalid constructor output arguments",
2212 meth.get_name ().c_str ()); 2104 meth.get_name ().c_str ());
2226 { 2118 {
2227 std::map<std::string,cdef_method> meths; 2119 std::map<std::string,cdef_method> meths;
2228 2120
2229 find_methods (meths, false); 2121 find_methods (meths, false);
2230 2122
2231 if (! error_state) 2123 Cell c (meths.size (), 1);
2232 { 2124
2233 Cell c (meths.size (), 1); 2125 int idx = 0;
2234 2126
2235 int idx = 0; 2127 for (std::map<std::string,cdef_method>::const_iterator
2236 2128 it = meths.begin (); it != meths.end (); ++it, ++idx)
2237 for (std::map<std::string,cdef_method>::const_iterator 2129 c (idx, 0) = to_ov (it->second);
2238 it = meths.begin (); it != meths.end (); ++it, ++idx) 2130
2239 c (idx, 0) = to_ov (it->second); 2131 return c;
2240
2241 return c;
2242 }
2243
2244 return Cell ();
2245 } 2132 }
2246 2133
2247 void 2134 void
2248 cdef_class::cdef_class_rep::find_methods (std::map<std::string, 2135 cdef_class::cdef_class_rep::find_methods (std::map<std::string,
2249 cdef_method>& meths, 2136 cdef_method>& meths,
2281 2168
2282 for (int i = 0; i < super_classes.numel (); i++) 2169 for (int i = 0; i < super_classes.numel (); i++)
2283 { 2170 {
2284 cdef_class cls = lookup_class (super_classes(i)); 2171 cdef_class cls = lookup_class (super_classes(i));
2285 2172
2286 if (! error_state) 2173 cls.get_rep ()->find_methods (meths, true);
2287 cls.get_rep ()->find_methods (meths, true);
2288 else
2289 break;
2290 } 2174 }
2291 } 2175 }
2292 2176
2293 cdef_property 2177 cdef_property
2294 cdef_class::cdef_class_rep::find_property (const std::string& nm) 2178 cdef_class::cdef_class_rep::find_property (const std::string& nm)
2309 2193
2310 for (int i = 0; i < super_classes.numel (); i++) 2194 for (int i = 0; i < super_classes.numel (); i++)
2311 { 2195 {
2312 cdef_class cls = lookup_class (super_classes(i)); 2196 cdef_class cls = lookup_class (super_classes(i));
2313 2197
2314 if (! error_state) 2198 cdef_property prop = cls.find_property (nm);
2315 { 2199
2316 cdef_property prop = cls.find_property (nm); 2200 if (prop.ok ())
2317 2201 return prop;
2318 if (prop.ok ())
2319 return prop;
2320 }
2321 } 2202 }
2322 2203
2323 return cdef_property (); 2204 return cdef_property ();
2324 } 2205 }
2325 2206
2336 { 2217 {
2337 std::map<std::string,cdef_property> props; 2218 std::map<std::string,cdef_property> props;
2338 2219
2339 props = get_property_map (mode); 2220 props = get_property_map (mode);
2340 2221
2341 if (! error_state) 2222 Cell c (props.size (), 1);
2342 { 2223
2343 Cell c (props.size (), 1); 2224 int idx = 0;
2344 2225
2345 int idx = 0; 2226 for (std::map<std::string,cdef_property>::const_iterator
2346 2227 it = props.begin (); it != props.end (); ++it, ++idx)
2347 for (std::map<std::string,cdef_property>::const_iterator 2228 c (idx, 0) = to_ov (it->second);
2348 it = props.begin (); it != props.end (); ++it, ++idx) 2229
2349 c (idx, 0) = to_ov (it->second); 2230 return c;
2350
2351 return c;
2352 }
2353
2354 return Cell ();
2355 } 2231 }
2356 2232
2357 std::map<std::string, cdef_property> 2233 std::map<std::string, cdef_property>
2358 cdef_class::cdef_class_rep::get_property_map (int mode) 2234 cdef_class::cdef_class_rep::get_property_map (int mode)
2359 { 2235 {
2369 cdef_property>& props, 2245 cdef_property>& props,
2370 int mode) 2246 int mode)
2371 { 2247 {
2372 property_const_iterator it; 2248 property_const_iterator it;
2373 2249
2374 for (it = property_map.begin (); ! error_state && it != property_map.end (); 2250 for (it = property_map.begin (); it != property_map.end (); ++it)
2375 ++it)
2376 { 2251 {
2377 std::string nm = it->second.get_name (); 2252 std::string nm = it->second.get_name ();
2378 2253
2379 if (props.find (nm) == props.end ()) 2254 if (props.find (nm) == props.end ())
2380 { 2255 {
2393 2268
2394 // Look into superclasses 2269 // Look into superclasses
2395 2270
2396 Cell super_classes = get ("SuperClasses").cell_value (); 2271 Cell super_classes = get ("SuperClasses").cell_value ();
2397 2272
2398 for (int i = 0; ! error_state && i < super_classes.numel (); i++) 2273 for (int i = 0; i < super_classes.numel (); i++)
2399 { 2274 {
2400 cdef_class cls = lookup_class (super_classes(i)); 2275 cdef_class cls = lookup_class (super_classes(i));
2401 2276
2402 if (! error_state) 2277 cls.get_rep ()->find_properties (props,
2403 cls.get_rep ()->find_properties (props, 2278 (mode == property_all
2404 (mode == property_all ? 2279 ? property_all
2405 property_all : 2280 : property_inherited));
2406 property_inherited));
2407 else
2408 break;
2409 } 2281 }
2410 } 2282 }
2411 2283
2412 void 2284 void
2413 cdef_class::cdef_class_rep::find_names (std::set<std::string>& names, 2285 cdef_class::cdef_class_rep::find_names (std::set<std::string>& names,
2414 bool all) 2286 bool all)
2415 { 2287 {
2416 load_all_methods (); 2288 load_all_methods ();
2417 2289
2418 for (method_const_iterator it = method_map.begin (); 2290 for (method_const_iterator it = method_map.begin ();
2419 ! error_state && it != method_map.end(); ++it) 2291 it != method_map.end(); ++it)
2420 { 2292 {
2421 if (! it->second.is_constructor ()) 2293 if (! it->second.is_constructor ())
2422 { 2294 {
2423 std::string nm = it->second.get_name (); 2295 std::string nm = it->second.get_name ();
2424 2296
2434 names.insert (nm); 2306 names.insert (nm);
2435 } 2307 }
2436 } 2308 }
2437 2309
2438 for (property_const_iterator it = property_map.begin (); 2310 for (property_const_iterator it = property_map.begin ();
2439 ! error_state && it != property_map.end (); ++it) 2311 it != property_map.end (); ++it)
2440 { 2312 {
2441 std::string nm = it->second.get_name (); 2313 std::string nm = it->second.get_name ();
2442 2314
2443 if (! all) 2315 if (! all)
2444 { 2316 {
2454 2326
2455 // Look into superclasses 2327 // Look into superclasses
2456 2328
2457 Cell super_classes = get ("SuperClasses").cell_value (); 2329 Cell super_classes = get ("SuperClasses").cell_value ();
2458 2330
2459 for (int i = 0; ! error_state && i < super_classes.numel (); i++) 2331 for (int i = 0; i < super_classes.numel (); i++)
2460 { 2332 {
2461 cdef_class cls = lookup_class (super_classes(i)); 2333 cdef_class cls = lookup_class (super_classes(i));
2462 2334
2463 if (! error_state) 2335 cls.get_rep ()->find_names (names, all);
2464 cls.get_rep ()->find_names (names, all);
2465 else
2466 break;
2467 } 2336 }
2468 } 2337 }
2469 2338
2470 string_vector 2339 string_vector
2471 cdef_class::cdef_class_rep::get_names (void) 2340 cdef_class::cdef_class_rep::get_names (void)
2472 { 2341 {
2473 std::set<std::string> names; 2342 std::set<std::string> names;
2474 2343
2475 find_names (names, false); 2344 find_names (names, false);
2476 2345
2477 if (! error_state) 2346 string_vector v (names.size ());
2478 { 2347
2479 string_vector v (names.size ()); 2348 int idx = 0;
2480 2349 for (std::set<std::string>::const_iterator it = names.begin ();
2481 int idx = 0; 2350 it != names.end (); ++it, ++idx)
2482 for (std::set<std::string>::const_iterator it = names.begin (); 2351 v[idx] = *it;
2483 it != names.end (); ++it, ++idx) 2352
2484 v[idx] = *it; 2353 return v.sort (true);
2485
2486 return v.sort (true);
2487 }
2488
2489 return string_vector ();
2490 } 2354 }
2491 2355
2492 void 2356 void
2493 cdef_class::cdef_class_rep::delete_object (cdef_object obj) 2357 cdef_class::cdef_class_rep::delete_object (cdef_object obj)
2494 { 2358 {
2513 2377
2514 for (int i = 0; i < super_classes.numel (); i++) 2378 for (int i = 0; i < super_classes.numel (); i++)
2515 { 2379 {
2516 cdef_class cls = lookup_class (super_classes(i)); 2380 cdef_class cls = lookup_class (super_classes(i));
2517 2381
2518 if (!error_state) 2382 cls.delete_object (obj);
2519 cls.delete_object (obj);
2520 } 2383 }
2521 } 2384 }
2522 2385
2523 octave_value_list 2386 octave_value_list
2524 cdef_class::cdef_class_rep::meta_subsref (const std::string& type, 2387 cdef_class::cdef_class_rep::meta_subsref (const std::string& type,
2601 default: 2464 default:
2602 error ("invalid meta.class indexing"); 2465 error ("invalid meta.class indexing");
2603 break; 2466 break;
2604 } 2467 }
2605 2468
2606 if (! error_state) 2469 if (type.length () > skip && idx.size () > skip && ! retval.empty ())
2607 { 2470 retval = retval(0).next_subsref (nargout, type, idx, skip);
2608 if (type.length () > skip && idx.size () > skip && ! retval.empty ())
2609 retval = retval(0).next_subsref (nargout, type, idx, skip);
2610 }
2611 2471
2612 return retval; 2472 return retval;
2613 } 2473 }
2614 2474
2615 void 2475 void
2624 // Populate the object with default property values 2484 // Populate the object with default property values
2625 2485
2626 std::list<cdef_class> super_classes = lookup_classes ( 2486 std::list<cdef_class> super_classes = lookup_classes (
2627 get ("SuperClasses").cell_value ()); 2487 get ("SuperClasses").cell_value ());
2628 2488
2629 if (! error_state) 2489 for (std::list<cdef_class>::iterator it = super_classes.begin ();
2630 { 2490 it != super_classes.end (); ++it)
2631 for (std::list<cdef_class>::iterator it = super_classes.begin (); 2491 it->initialize_object (obj);
2632 ! error_state && it != super_classes.end (); ++it) 2492
2633 it->initialize_object (obj); 2493 for (property_const_iterator it = property_map.begin ();
2634 2494 it != property_map.end (); ++it)
2635 if (! error_state) 2495 {
2636 { 2496 if (! it->second.get ("Dependent").bool_value ())
2637 for (property_const_iterator it = property_map.begin (); 2497 {
2638 ! error_state && it != property_map.end (); ++it) 2498 octave_value pvalue = it->second.get ("DefaultValue");
2639 { 2499
2640 if (! it->second.get ("Dependent").bool_value ()) 2500 if (pvalue.is_defined ())
2641 { 2501 obj.put (it->first, pvalue);
2642 octave_value pvalue = it->second.get ("DefaultValue"); 2502 else
2643 2503 obj.put (it->first, octave_value (Matrix ()));
2644 if (pvalue.is_defined ()) 2504 }
2645 obj.put (it->first, pvalue); 2505 }
2646 else 2506
2647 obj.put (it->first, octave_value (Matrix ())); 2507 refcount++;
2648 } 2508 obj.mark_for_construction (cdef_class (this));
2649 }
2650
2651 if (! error_state)
2652 {
2653 refcount++;
2654 obj.mark_for_construction (cdef_class (this));
2655 }
2656 }
2657 }
2658 } 2509 }
2659 2510
2660 void 2511 void
2661 cdef_class::cdef_class_rep::run_constructor (cdef_object& obj, 2512 cdef_class::cdef_class_rep::run_constructor (cdef_object& obj,
2662 const octave_value_list& args) 2513 const octave_value_list& args)
2663 { 2514 {
2664 octave_value_list empty_args; 2515 octave_value_list empty_args;
2665 2516
2666 for (std::list<cdef_class>::const_iterator it = implicit_ctor_list.begin (); 2517 for (std::list<cdef_class>::const_iterator it = implicit_ctor_list.begin ();
2667 ! error_state && it != implicit_ctor_list.end (); ++it) 2518 it != implicit_ctor_list.end (); ++it)
2668 { 2519 {
2669 cdef_class supcls = lookup_class (*it); 2520 cdef_class supcls = lookup_class (*it);
2670 2521
2671 if (! error_state) 2522 supcls.run_constructor (obj, empty_args);
2672 supcls.run_constructor (obj, empty_args); 2523 }
2673 }
2674
2675 if (error_state)
2676 return;
2677 2524
2678 std::string cls_name = get_name (); 2525 std::string cls_name = get_name ();
2679 std::string ctor_name = get_base_name (cls_name); 2526 std::string ctor_name = get_base_name (cls_name);
2680 2527
2681 cdef_method ctor = find_method (ctor_name); 2528 cdef_method ctor = find_method (ctor_name);
2686 octave_value_list ctor_retval; 2533 octave_value_list ctor_retval;
2687 2534
2688 ctor_args.prepend (to_ov (obj)); 2535 ctor_args.prepend (to_ov (obj));
2689 ctor_retval = ctor.execute (ctor_args, 1, true, "constructor"); 2536 ctor_retval = ctor.execute (ctor_args, 1, true, "constructor");
2690 2537
2691 if (! error_state) 2538 if (ctor_retval.length () == 1)
2692 { 2539 obj = to_cdef (ctor_retval(0));
2693 if (ctor_retval.length () == 1) 2540 else
2694 obj = to_cdef (ctor_retval(0)); 2541 {
2695 else 2542 error ("%s: invalid number of output arguments for classdef constructor",
2696 { 2543 ctor_name.c_str ());
2697 error ("%s: invalid number of output arguments for classdef constructor", 2544 return;
2698 ctor_name.c_str ());
2699 return;
2700 }
2701 } 2545 }
2702 } 2546 }
2703 2547
2704 obj.mark_as_constructed (wrap ()); 2548 obj.mark_as_constructed (wrap ());
2705 } 2549 }
2707 octave_value 2551 octave_value
2708 cdef_class::cdef_class_rep::construct (const octave_value_list& args) 2552 cdef_class::cdef_class_rep::construct (const octave_value_list& args)
2709 { 2553 {
2710 cdef_object obj = construct_object (args); 2554 cdef_object obj = construct_object (args);
2711 2555
2712 if (! error_state && obj.ok ()) 2556 if (obj.ok ())
2713 return to_ov (obj); 2557 return to_ov (obj);
2714 2558
2715 return octave_value (); 2559 return octave_value ();
2716 } 2560 }
2717 2561
2778 obj = cdef_object (new value_cdef_object ()); 2622 obj = cdef_object (new value_cdef_object ());
2779 obj.set_class (wrap ()); 2623 obj.set_class (wrap ());
2780 2624
2781 initialize_object (obj); 2625 initialize_object (obj);
2782 2626
2783 if (! error_state) 2627 run_constructor (obj, args);
2784 { 2628
2785 run_constructor (obj, args); 2629 return obj;
2786
2787 if (! error_state)
2788 return obj;
2789 }
2790 } 2630 }
2791 } 2631 }
2792 else 2632 else
2793 error ("cannot instantiate object for abstract class `%s'", 2633 error ("cannot instantiate object for abstract class `%s'",
2794 get_name ().c_str ()); 2634 get_name ().c_str ());
2851 2691
2852 if (t->superclass_list ()) 2692 if (t->superclass_list ())
2853 { 2693 {
2854 for (tree_classdef_superclass_list::iterator it = 2694 for (tree_classdef_superclass_list::iterator it =
2855 t->superclass_list ()->begin (); 2695 t->superclass_list ()->begin ();
2856 ! error_state && it != t->superclass_list ()->end (); ++it) 2696 it != t->superclass_list ()->end (); ++it)
2857 { 2697 {
2858 std::string sclass_name = (*it)->class_name (); 2698 std::string sclass_name = (*it)->class_name ();
2859 2699
2860 #if DEBUG_TRACE 2700 #if DEBUG_TRACE
2861 std::cerr << "superclass: " << sclass_name << std::endl; 2701 std::cerr << "superclass: " << sclass_name << std::endl;
2862 #endif 2702 #endif
2863 2703
2864 cdef_class sclass = lookup_class (sclass_name); 2704 cdef_class sclass = lookup_class (sclass_name);
2865 2705
2866 if (! error_state) 2706 if (! sclass.get ("Sealed").bool_value ())
2707 slist.push_back (sclass);
2708 else
2867 { 2709 {
2868 if (! sclass.get ("Sealed").bool_value ()) 2710 error ("`%s' cannot inherit from `%s', because it is sealed",
2869 slist.push_back (sclass); 2711 full_class_name.c_str (), sclass_name.c_str ());
2870 else 2712 return retval;
2871 {
2872 error ("`%s' cannot inherit from `%s', because it is sealed",
2873 full_class_name.c_str (), sclass_name.c_str ());
2874 return retval;
2875 }
2876 } 2713 }
2877 else
2878 return retval;
2879 2714
2880 } 2715 }
2881 } 2716 }
2882 2717
2883 retval = ::make_class (full_class_name, slist); 2718 retval = ::make_class (full_class_name, slist);
2884 2719
2885 if (error_state)
2886 return cdef_class ();
2887
2888 // Package owning this class 2720 // Package owning this class
2889 2721
2890 if (! t->package_name ().empty ()) 2722 if (! t->package_name ().empty ())
2891 { 2723 {
2892 cdef_package pack = cdef_manager::find_package (t->package_name ()); 2724 cdef_package pack = cdef_manager::find_package (t->package_name ());
2893 2725
2894 if (! error_state && pack.ok ()) 2726 if (pack.ok ())
2895 retval.put ("ContainingPackage", to_ov (pack)); 2727 retval.put ("ContainingPackage", to_ov (pack));
2896 } 2728 }
2897 2729
2898 // Class attributes 2730 // Class attributes
2899 2731
3200 3032
3201 args(0) = to_ov (obj); 3033 args(0) = to_ov (obj);
3202 3034
3203 args = execute_ov (get_fcn, args, 1); 3035 args = execute_ov (get_fcn, args, 1);
3204 3036
3205 if (! error_state) 3037 retval = args(0);
3206 retval = args(0);
3207 } 3038 }
3208 3039
3209 return retval; 3040 return retval;
3210 } 3041 }
3211 3042
3266 args(0) = to_ov (obj); 3097 args(0) = to_ov (obj);
3267 args(1) = val; 3098 args(1) = val;
3268 3099
3269 args = execute_ov (set_fcn, args, 1); 3100 args = execute_ov (set_fcn, args, 1);
3270 3101
3271 if (! error_state) 3102 if (args.length () > 0 && args(0).is_defined ())
3272 { 3103 {
3273 if (args.length () > 0 && args(0).is_defined ()) 3104 if (args (0).is_classdef_object ())
3274 { 3105 {
3275 if (args (0).is_classdef_object ()) 3106 cdef_object new_obj = to_cdef (args(0));
3276 { 3107
3277 cdef_object new_obj = to_cdef (args(0)); 3108 obj = new_obj;
3278
3279 if (! error_state)
3280 obj = new_obj;
3281 }
3282 else
3283 ::warning ("set-method of property `%s' returned a non-classdef object",
3284 get_name ().c_str ());
3285 } 3109 }
3110 else
3111 ::warning ("set-method of property `%s' returned a non-classdef object",
3112 get_name ().c_str ());
3286 } 3113 }
3287 } 3114 }
3288 } 3115 }
3289 3116
3290 bool 3117 bool
3291 cdef_property::cdef_property_rep::check_get_access (void) const 3118 cdef_property::cdef_property_rep::check_get_access (void) const
3292 { 3119 {
3293 cdef_class cls (to_cdef (get ("DefiningClass"))); 3120 cdef_class cls (to_cdef (get ("DefiningClass")));
3294 3121
3295 if (! error_state) 3122 return ::check_access (cls, get ("GetAccess"), std::string (),
3296 return ::check_access (cls, get ("GetAccess"), std::string (), 3123 get_name (), false);
3297 get_name (), false);
3298 3124
3299 return false; 3125 return false;
3300 } 3126 }
3301 3127
3302 bool 3128 bool
3303 cdef_property::cdef_property_rep::check_set_access (void) const 3129 cdef_property::cdef_property_rep::check_set_access (void) const
3304 { 3130 {
3305 cdef_class cls (to_cdef (get ("DefiningClass"))); 3131 cdef_class cls (to_cdef (get ("DefiningClass")));
3306 3132
3307 if (! error_state) 3133 return ::check_access (cls, get ("SetAccess"), std::string (),
3308 return ::check_access (cls, get ("SetAccess"), std::string (), 3134 get_name (), true);
3309 get_name (), true);
3310 3135
3311 return false; 3136 return false;
3312 } 3137 }
3313 3138
3314 void 3139 void
3375 3200
3376 if (! get ("Abstract").bool_value ()) 3201 if (! get ("Abstract").bool_value ())
3377 { 3202 {
3378 check_method (); 3203 check_method ();
3379 3204
3380 if (! error_state && function.is_defined ()) 3205 if (function.is_defined ())
3381 { 3206 retval = execute_ov (function, args, nargout);
3382 retval = execute_ov (function, args, nargout);
3383 }
3384 } 3207 }
3385 else 3208 else
3386 error ("%s: cannot execute abstract method", 3209 error ("%s: cannot execute abstract method",
3387 get ("Name").string_value ().c_str ()); 3210 get ("Name").string_value ().c_str ());
3388 3211
3406 3229
3407 if (! get ("Abstract").bool_value ()) 3230 if (! get ("Abstract").bool_value ())
3408 { 3231 {
3409 check_method (); 3232 check_method ();
3410 3233
3411 if (! error_state && function.is_defined ()) 3234 if (function.is_defined ())
3412 { 3235 {
3413 octave_value_list new_args; 3236 octave_value_list new_args;
3414 3237
3415 new_args.resize (args.length () + 1); 3238 new_args.resize (args.length () + 1);
3416 3239
3440 bool 3263 bool
3441 cdef_method::cdef_method_rep::check_access (void) const 3264 cdef_method::cdef_method_rep::check_access (void) const
3442 { 3265 {
3443 cdef_class cls (to_cdef (get ("DefiningClass"))); 3266 cdef_class cls (to_cdef (get ("DefiningClass")));
3444 3267
3445 if (! error_state) 3268 return ::check_access (cls, get ("Access"), get_name ());
3446 return ::check_access (cls, get ("Access"), get_name ());
3447
3448 return false;
3449 } 3269 }
3450 3270
3451 octave_value_list 3271 octave_value_list
3452 cdef_method::cdef_method_rep::meta_subsref 3272 cdef_method::cdef_method_rep::meta_subsref
3453 (const std::string& type, const std::list<octave_value_list>& idx, 3273 (const std::string& type, const std::list<octave_value_list>& idx,
3464 default: 3284 default:
3465 error ("invalid meta.method indexing"); 3285 error ("invalid meta.method indexing");
3466 break; 3286 break;
3467 } 3287 }
3468 3288
3469 if (! error_state) 3289 if (type.length () > 1 && idx.size () > 1 && ! retval.empty ())
3470 { 3290 retval = retval(0).next_subsref (nargout, type, idx, 1);
3471 if (type.length () > 1 && idx.size () > 1 && ! retval.empty ())
3472 retval = retval(0).next_subsref (nargout, type, idx, 1);
3473 }
3474 3291
3475 return retval; 3292 return retval;
3476 } 3293 }
3477 3294
3478 static cdef_package 3295 static cdef_package
3662 { 3479 {
3663 if (o.is_function ()) 3480 if (o.is_function ())
3664 { 3481 {
3665 octave_function* fcn = o.function_value (); 3482 octave_function* fcn = o.function_value ();
3666 3483
3667 if (! error_state) 3484 // NOTE: the case where the package query is the last
3485 // part of this subsref index is handled in the parse
3486 // tree, because there is some logic to handle magic
3487 // "end" that makes it impossible to execute the
3488 // function call at this stage.
3489
3490 if (type.size () > 1
3491 && ! fcn->is_postfix_index_handled (type[1]))
3668 { 3492 {
3669 // NOTE: the case where the package query is the last 3493 octave_value_list tmp_args;
3670 // part of this subsref index is handled in the parse 3494
3671 // tree, because there is some logic to handle magic 3495 retval = o.do_multi_index_op (nargout,
3672 // "end" that makes it impossible to execute the 3496 tmp_args);
3673 // function call at this stage.
3674
3675 if (type.size () > 1
3676 && ! fcn->is_postfix_index_handled (type[1]))
3677 {
3678 octave_value_list tmp_args;
3679
3680 retval = o.do_multi_index_op (nargout,
3681 tmp_args);
3682 }
3683 else
3684 retval(0) = o;
3685
3686 if (type.size () > 1 && idx.size () > 1)
3687 retval = retval(0).next_subsref (nargout, type,
3688 idx, 1);
3689 } 3497 }
3498 else
3499 retval(0) = o;
3500
3501 if (type.size () > 1 && idx.size () > 1)
3502 retval = retval(0).next_subsref (nargout, type,
3503 idx, 1);
3690 } 3504 }
3691 else if (type.size () > 1 && idx.size () > 1) 3505 else if (type.size () > 1 && idx.size () > 1)
3692 retval = o.next_subsref (nargout, type, idx, 1); 3506 retval = o.next_subsref (nargout, type, idx, 1);
3693 else 3507 else
3694 retval(0) = o; 3508 retval(0) = o;