[master] e673718d1 Bury the knowledge of type methods in type code

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Jul 2 12:49:07 UTC 2020


commit e673718d19d2faa244858fc708fffabf594508b9
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri Nov 29 07:52:37 2019 +0100

    Bury the knowledge of type methods in type code
    
    This enables the possibility for other kinds of SYM_METHOD symbols with
    different parsing rules.

diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 874c63c15..14f2975a6 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -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 */
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index be0ee4aa3..71c618a83 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.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);
-		}
 	}
 }
 
diff --git a/lib/libvcc/vcc_types.c b/lib/libvcc/vcc_types.c
index 1292ec27a..b49eaa9f6 100644
--- a/lib/libvcc/vcc_types.c
+++ b/lib/libvcc/vcc_types.c
@@ -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)
 {


More information about the varnish-commit mailing list