Commit e673718d authored by Dridi Boukelmoune's avatar Dridi Boukelmoune

Bury the knowledge of type methods in type code

This enables the possibility for other kinds of SYM_METHOD symbols with
different parsing rules.
parent 2fb26ab7
......@@ -100,24 +100,6 @@ struct token {
typedef const struct type *vcc_type_t;
/*
* A type attribute is information already existing, requiring no processing
* or resource usage.
*
* A type method is a call and may do significant processing, change things,
* eat workspace etc.
*
* XXX: type methods might move in a more comprehensive direction.
*/
struct vcc_method {
unsigned magic;
#define VCC_METHOD_MAGIC 0x594108cd
vcc_type_t type;
const char *name;
const char *impl;
int func;
};
struct type {
unsigned magic;
#define TYPE_MAGIC 0xfae932d9
......@@ -353,6 +335,7 @@ void vcc_Expr_Init(struct vcc *tl);
sym_expr_t vcc_Eval_Var;
sym_expr_t vcc_Eval_Handle;
sym_expr_t vcc_Eval_SymFunc;
sym_expr_t vcc_Eval_TypeMethod;
void vcc_Eval_Func(struct vcc *, const struct vjsn_val *,
const char *, const struct symbol *);
void VCC_GlobalSymbol(struct symbol *, vcc_type_t fmt, const char *pfx);
......@@ -427,6 +410,7 @@ void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b,
/* vcc_types.c */
vcc_type_t VCC_Type(const char *p);
const char * VCC_Type_EvalMethod(struct vcc *, const struct symbol *);
void vcc_Type_Init(struct vcc *tl);
/* vcc_var.c */
......
......@@ -819,11 +819,23 @@ vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
* Expr5 [ '.' (type_attribute | type_method()) ]*
*/
void
vcc_Eval_TypeMethod(struct vcc *tl, struct expr **e, struct token *t,
struct symbol *sym, vcc_type_t fmt)
{
const char *impl;
(void)t;
impl = VCC_Type_EvalMethod(tl, sym);
ERRCHK(tl);
AN(impl);
*e = vcc_expr_edit(tl, fmt, impl, *e, NULL);
}
static void
vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
{
const struct vcc_method *vm;
const struct symbol *sym;
struct symbol *sym;
*e = NULL;
vcc_expr5(tl, e, fmt);
......@@ -842,21 +854,14 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
vcc_ErrWhere(tl, tl->t);
return;
}
CAST_OBJ_NOTNULL(vm, sym->eval_priv, VCC_METHOD_MAGIC);
vcc_NextToken(tl);
*e = vcc_expr_edit(tl, vm->type, vm->impl, *e, NULL);
AN(sym->eval);
sym->eval(tl, e, tl->t, sym, sym->type);
ERRCHK(tl);
if ((*e)->fmt == STRING) {
(*e)->fmt = STRINGS;
(*e)->nstr = 1;
}
if (vm->func) {
ExpectErr(tl, '(');
vcc_NextToken(tl);
ExpectErr(tl, ')');
vcc_NextToken(tl);
}
}
}
......
......@@ -36,6 +36,24 @@
#include "vcc_compile.h"
/*
* A type attribute is information already existing, requiring no processing
* or resource usage.
*
* A type method is a call and may do significant processing, change things,
* eat workspace etc.
*
* XXX: type methods might move in a more comprehensive direction.
*/
struct vcc_method {
unsigned magic;
#define VCC_METHOD_MAGIC 0x594108cd
vcc_type_t type;
const char *name;
const char *impl;
int func;
};
const struct type ACL[1] = {{
.magic = TYPE_MAGIC,
.name = "ACL",
......@@ -237,12 +255,37 @@ vcc_type_init(struct vcc *tl, vcc_type_t type)
break;
AN(sym);
sym->type = vm->type;
sym->eval = vcc_Eval_TypeMethod;
sym->eval_priv = vm;
}
VSB_destroy(&buf);
}
const char *
VCC_Type_EvalMethod(struct vcc *tl, const struct symbol *sym)
{
const struct vcc_method *vm;
AN(sym);
AN(sym->kind == SYM_METHOD);
CAST_OBJ_NOTNULL(vm, sym->eval_priv, VCC_METHOD_MAGIC);
vcc_NextToken(tl);
if (vm->func) {
Expect(tl, '(');
if (tl->err)
return (NULL);
vcc_NextToken(tl);
Expect(tl, ')');
if (tl->err)
return (NULL);
vcc_NextToken(tl);
}
return (vm->impl);
}
void
vcc_Type_Init(struct vcc *tl)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment