From 542dcaa0ec7fe63f1fce0a4507c2174ec28b48d6 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Fri, 19 Apr 2013 10:57:46 +0000 Subject: the C runtime and the Python binding now have an API for parser evaluation. The API computes PARSEVAL and Exact Match for a given tree. As a side effect the abstract trees in Python are now compared for equality by value and not by reference --- src/runtime/c/pgf/expr.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) (limited to 'src/runtime/c/pgf/expr.c') diff --git a/src/runtime/c/pgf/expr.c b/src/runtime/c/pgf/expr.c index 494708e8c..13093d14f 100644 --- a/src/runtime/c/pgf/expr.c +++ b/src/runtime/c/pgf/expr.c @@ -368,6 +368,79 @@ pgf_read_expr(GuReader* rdr, GuPool* pool, GuExn* err) return expr; } +bool +pgf_literal_eq(PgfLiteral lit1, PgfLiteral lit2) +{ + GuVariantInfo ei1 = gu_variant_open(lit1); + GuVariantInfo ei2 = gu_variant_open(lit2); + + if (ei1.tag != ei2.tag) + return false; + + switch (ei1.tag) { + case PGF_LITERAL_STR: { + PgfLiteralStr* lit1 = ei1.data; + PgfLiteralStr* lit2 = ei2.data; + return gu_string_eq(lit1->val, lit2->val); + } + case PGF_LITERAL_INT: { + PgfLiteralInt* lit1 = ei1.data; + PgfLiteralInt* lit2 = ei2.data; + return (lit1->val == lit2->val); + } + case PGF_LITERAL_FLT: { + PgfLiteralFlt* lit1 = ei1.data; + PgfLiteralFlt* lit2 = ei2.data; + return (lit1->val == lit2->val); + } + default: + gu_impossible(); + } + + return false; +} + +bool +pgf_expr_eq(PgfExpr e1, PgfExpr e2) +{ + GuVariantInfo ei1 = gu_variant_open(e1); + GuVariantInfo ei2 = gu_variant_open(e2); + + if (ei1.tag != ei2.tag) + return false; + + switch (ei1.tag) { + case PGF_EXPR_FUN: { + PgfExprFun* fun1 = ei1.data; + PgfExprFun* fun2 = ei2.data; + return gu_string_eq(fun1->fun, fun2->fun); + } + case PGF_EXPR_APP: { + PgfExprApp* app1 = ei1.data; + PgfExprApp* app2 = ei2.data; + return (pgf_expr_eq(app1->fun,app2->fun) && + pgf_expr_eq(app1->arg,app2->arg)); + } + case PGF_EXPR_LIT: { + PgfExprLit* lit1 = ei1.data; + PgfExprLit* lit2 = ei2.data; + return (pgf_literal_eq(lit1->lit,lit2->lit)); + } + case PGF_EXPR_META: + return true; + case PGF_EXPR_ABS: + case PGF_EXPR_VAR: + case PGF_EXPR_TYPED: + case PGF_EXPR_IMPL_ARG: + gu_impossible(); + break; + default: + gu_impossible(); + } + + return false; +} + void pgf_print_literal(PgfLiteral lit, GuWriter* wtr, GuExn* err) @@ -420,7 +493,6 @@ pgf_print_expr(PgfExpr expr, int prec, } break; } - case PGF_EXPR_ABS: case PGF_EXPR_LIT: { PgfExprLit* lit = ei.data; pgf_print_literal(lit->lit, wtr, err); @@ -429,6 +501,7 @@ pgf_print_expr(PgfExpr expr, int prec, case PGF_EXPR_META: gu_putc('?', wtr, err); break; + case PGF_EXPR_ABS: case PGF_EXPR_VAR: case PGF_EXPR_TYPED: case PGF_EXPR_IMPL_ARG: -- cgit v1.2.3