static void fput_loc(struct exec *loc, FILE *f);
static void type_err(struct parse_context *c,
char *fmt, struct exec *loc,
- struct type *t1, int rules, struct type *t2);
+ struct type *t1, enum val_rules rules, struct type *t2);
static void tok_err(struct parse_context *c, char *fmt, struct token *t);
###### core functions
static void type_err(struct parse_context *c,
char *fmt, struct exec *loc,
- struct type *t1, int rules, struct type *t2)
+ struct type *t1, enum val_rules rules, struct type *t2)
{
fprintf(stderr, "%s:", c->file_name);
fput_loc(loc, stderr);
###### forward decls
static struct type *propagate_types(struct exec *prog, struct parse_context *c, enum prop_err *perr,
- struct type *type, int rules);
+ struct type *type, enum val_rules rules);
###### core functions
static struct type *__propagate_types(struct exec *prog, struct parse_context *c, enum prop_err *perr,
enum prop_err *perr_local,
- struct type *type, int rules)
+ struct type *type, enum val_rules rules)
{
struct type *t;
}
static struct type *propagate_types(struct exec *prog, struct parse_context *c, enum prop_err *perr,
- struct type *type, int rules)
+ struct type *type, enum val_rules rules)
{
int pre_err = c->parse_error;
enum prop_err perr_local = 0;
###### forward decls
static void free_value(struct type *type, struct value *v);
- static int type_compat(struct type *require, struct type *have, int rules);
+ static int type_compat(struct type *require, struct type *have, enum val_rules rules);
static void type_print(struct type *type, FILE *f);
static void val_init(struct type *type, struct value *v);
static void dup_value(struct type *type,
###### type functions
- int (*compat)(struct type *this, struct type *other);
+ int (*compat)(struct type *this, struct type *other, enum val_rules rules);
###### ast functions
- static int type_compat(struct type *require, struct type *have, int rules)
+ static int type_compat(struct type *require, struct type *have,
+ enum val_rules rules)
{
if ((rules & Rboolok) && have == Tbool)
return 1; // NOTEST
return 1;
if (require->compat)
- return require->compat(require, have);
+ return require->compat(require, have, rules);
return require == have;
}
*perr |= Eruntime;
if (v->constant)
*perr |= Econst;
- if (!type)
- return v->type;
- return type;
+ return v->type;
}
###### interp exec cases
free(ptr);
}
- static int array_compat(struct type *require, struct type *have)
+ static int array_compat(struct type *require, struct type *have,
+ enum val_rules rules)
{
if (have->compat != require->compat)
return 0;
}
###### top level grammar
- DeclareStruct -> struct IDENTIFIER FieldBlock Newlines ${ {
- struct type *t;
- t = find_type(c, $ID.txt);
- if (!t)
- t = add_type(c, $ID.txt, &structure_prototype);
- else if (t->size >= 0) {
+ $*type
+ StructName -> IDENTIFIER ${ {
+ struct type *t = find_type(c, $ID.txt);
+
+ if (t && t->size >= 0) {
tok_err(c, "error: type already declared", &$ID);
tok_err(c, "info: this is location of declartion", &t->first_use);
- /* Create a new one - duplicate */
- t = add_type(c, $ID.txt, &structure_prototype);
- } else {
- struct type tmp = *t;
- *t = structure_prototype;
- t->name = tmp.name;
- t->next = tmp.next;
+ t = NULL;
}
- t->structure.field_list = $<FB;
+ if (!t)
+ t = add_type(c, $ID.txt, NULL);
t->first_use = $ID;
+ $0 = t;
+ } }$
+ $void
+ DeclareStruct -> struct StructName FieldBlock Newlines ${ {
+ struct type *t = $<SN;
+ struct type tmp = *t;
+
+ *t = structure_prototype;
+ t->name = tmp.name;
+ t->next = tmp.next;
+ t->first_use = tmp.first_use;
+
+ t->structure.field_list = $<FB;
} }$
$*fieldlist
/* Nothing to do here */
}
- static int reference_compat(struct type *require, struct type *have)
+ static int reference_compat(struct type *require, struct type *have,
+ enum val_rules rules)
{
if (have->compat != require->compat)
return 0;
| @ IDENTIFIER ${ {
struct type *t = find_type(c, $ID.txt);
if (!t) {
- t = add_type(c, $ID.txt, NULL);
- t->first_use = $ID;
+ t = add_type(c, $ID.txt, NULL); // UNTESTED
+ t->first_use = $ID; // UNTESTED
}
$0 = find_anon_type(c, &reference_prototype, "@%.*s",
$ID.txt.len, $ID.txt.txt);
val->function = NULL;
}
- static int function_compat(struct type *require, struct type *have)
+ static int function_compat(struct type *require, struct type *have,
+ enum val_rules rules)
{
// FIXME can I do anything here yet?
return 0;
return Tnone;
if (t) {
- if (propagate_types(b->right, c, perr_local, t, 0) != t)
- if (b->left->type == Xvar)
- type_err(c, "info: variable '%v' was set as %1 here.",
- cast(var, b->left)->var->where_set, t, rules, NULL);
+ propagate_types(b->right, c, perr_local, t, 0);
} else {
t = propagate_types(b->right, c, perr_local, NULL, 0);
if (t)
}
if (t && t->dup == NULL && !(*perr_local & Emaycopy))
type_err(c, "error: cannot assign value of type %1", b, t, 0, NULL);
+ if (b->left->type == Xvar && (*perr_local & Efail))
+ type_err(c, "info: variable '%v' was set as %1 here.",
+ cast(var, b->left)->var->where_set, t, rules, NULL);
return Tnone;
break;
struct value fn = {.function = code};
struct type *t;
var_block_close(c, CloseFunction, code);
- t = add_anon_type(c, &function_prototype,
- "func %.*s", name->name->name.len,
+ t = add_anon_type(c, &function_prototype,
+ "func %.*s", name->name->name.len,
name->name->name.txt);
name->type = t;
t->function.params = reorder_bilist(args);
all_ok = 0;
if (!v->type->function.inline_result &&
!v->type->function.return_type->dup) {
- type_err(c, "error: function cannot return value of type %1",
+ type_err(c, "error: function cannot return value of type %1",
v->where_decl, v->type->function.return_type, 0, NULL);
}