|
@@ -2099,6 +2099,28 @@ qi_value_t *qi_cast(qi_state_t *state, qi_type_t type, qi_value_t *value) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ case QI_REFERENCE: {
|
|
|
|
+ qi_value_t *meta;
|
|
|
|
+ if ((meta = qi_call_meta(state, &fail, value, "__ref", 1, value))) {
|
|
|
|
+ if (meta->type != QI_REFERENCE)
|
|
|
|
+ qi_throw_format(state, "__ref returned non-reference value (%s)",
|
|
|
|
+ _qi_type(state, meta));
|
|
|
|
+
|
|
|
|
+ return meta;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (fail)
|
|
|
|
+ goto leave;
|
|
|
|
+
|
|
|
|
+ switch (value->type) {
|
|
|
|
+ case QI_STRING:
|
|
|
|
+ return qi_make_ref(state, value->value.string);
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -3969,6 +3991,8 @@ qi_value_t *qi_builtin_chr(qi_state_t *state, qi_size_t pargc,
|
|
_qi_type(state, a));
|
|
_qi_type(state, a));
|
|
|
|
|
|
unsigned char c = (int)(a->value.number);
|
|
unsigned char c = (int)(a->value.number);
|
|
|
|
+ if (c == 0)
|
|
|
|
+ qi_throw_format(state, "illegal character code");
|
|
|
|
|
|
return qi_make_char(state, c);
|
|
return qi_make_char(state, c);
|
|
}
|
|
}
|
|
@@ -4291,6 +4315,38 @@ qi_value_t *qi_builtin_table(qi_state_t *state, qi_size_t pargc,
|
|
return qi_to_table(state, a);
|
|
return qi_to_table(state, a);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+qi_value_t *qi_builtin_ref(qi_state_t *state, qi_size_t pargc,
|
|
|
|
+ qi_list_t *pargs) {
|
|
|
|
+ qi_value_t *a = qi_list_data(pargs, 0);
|
|
|
|
+
|
|
|
|
+ return qi_to_ref(state, a);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+qi_value_t *qi_builtin_deref(qi_state_t *state, qi_size_t pargc,
|
|
|
|
+ qi_list_t *pargs) {
|
|
|
|
+ qi_value_t *a = qi_list_data(pargs, 0);
|
|
|
|
+
|
|
|
|
+ if (a->type != QI_REFERENCE)
|
|
|
|
+ qi_throw_format(state,
|
|
|
|
+ "expected first argument to be: reference, but got: %s",
|
|
|
|
+ _qi_type(state, a));
|
|
|
|
+
|
|
|
|
+ return qi_deref(state, a);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+qi_value_t *qi_builtin_ref_set(qi_state_t *state, qi_size_t pargc,
|
|
|
|
+ qi_list_t *pargs) {
|
|
|
|
+ qi_value_t *a = qi_list_data(pargs, 0);
|
|
|
|
+ qi_value_t *b = qi_list_data(pargs, 1);
|
|
|
|
+
|
|
|
|
+ if (a->type != QI_REFERENCE)
|
|
|
|
+ qi_throw_format(state,
|
|
|
|
+ "expected first argument to be: reference, but got: %s",
|
|
|
|
+ _qi_type(state, a));
|
|
|
|
+
|
|
|
|
+ return qi_set_ref(state, false, a, b);
|
|
|
|
+}
|
|
|
|
+
|
|
qi_value_t *qi_pseudomethod_func_call(qi_state_t *state, qi_size_t pargc,
|
|
qi_value_t *qi_pseudomethod_func_call(qi_state_t *state, qi_size_t pargc,
|
|
qi_list_t *pargs) {
|
|
qi_list_t *pargs) {
|
|
return qi_builtin_func_call(state, pargc, pargs);
|
|
return qi_builtin_func_call(state, pargc, pargs);
|
|
@@ -4510,6 +4566,10 @@ static void qi_state_setup(qi_state_t *state) {
|
|
qi_add_builtin(state, "list", 1, qi_builtin_list);
|
|
qi_add_builtin(state, "list", 1, qi_builtin_list);
|
|
qi_add_builtin(state, "tuple", 1, qi_builtin_tuple);
|
|
qi_add_builtin(state, "tuple", 1, qi_builtin_tuple);
|
|
qi_add_builtin(state, "table", 1, qi_builtin_table);
|
|
qi_add_builtin(state, "table", 1, qi_builtin_table);
|
|
|
|
+ qi_add_builtin(state, "ref", 1, qi_builtin_ref);
|
|
|
|
+
|
|
|
|
+ qi_add_builtin(state, "deref", 1, qi_builtin_deref);
|
|
|
|
+ qi_add_builtin(state, "ref_set", 2, qi_builtin_ref_set);
|
|
|
|
|
|
qi_add_pseudomethod(state, "file.write", 0, qi_pseudomethod_file_write);
|
|
qi_add_pseudomethod(state, "file.write", 0, qi_pseudomethod_file_write);
|
|
qi_add_pseudomethod(state, "file.read", 0, qi_pseudomethod_file_read);
|
|
qi_add_pseudomethod(state, "file.read", 0, qi_pseudomethod_file_read);
|