aboutsummaryrefslogtreecommitdiff
path: root/src/aterm-helper.pl
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-10-29 11:22:49 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-10-29 11:22:49 +0000
commita69534fc217666d53a418605de0ebb0879cbb2f7 (patch)
treeb91bc4123796ff607c0c0b3861fe45ed37028bf3 /src/aterm-helper.pl
parented09821859e8e585c8479a3c3bf95e76d518d66f (diff)
* Drop ATmake / ATMatcher also in handling store expressions.
Diffstat (limited to 'src/aterm-helper.pl')
-rwxr-xr-xsrc/aterm-helper.pl147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/aterm-helper.pl b/src/aterm-helper.pl
new file mode 100755
index 000000000..917b50852
--- /dev/null
+++ b/src/aterm-helper.pl
@@ -0,0 +1,147 @@
+#! /usr/bin/perl -w
+
+# This program generates C/C++ code for efficiently manipulating
+# ATerms. It generates functions to build and match ATerms according
+# to a set of constructor definitions defined in a file read from
+# standard input. A constructor is defined by a line with the
+# following format:
+#
+# SYM | ARGS | TYPE | FUN?
+#
+# where SYM is the name of the constructor, ARGS is a
+# whitespace-separated list of argument types, TYPE is the type of the
+# resulting ATerm (which should be `ATerm' or a type synonym for
+# `ATerm'), and the optional FUN is used to construct the names of the
+# build and match functions (it defaults to SYM; overriding it is
+# useful if there are overloaded constructors, e.g., with different
+# arities). Note that SYM may be empty.
+#
+# A line of the form
+#
+# VAR = EXPR
+#
+# causes a ATerm variable to be generated that is initialised to the
+# value EXPR.
+#
+# Finally, a line of the form
+#
+# init NAME
+#
+# causes the initialisation function to be called `NAME'. This
+# function must be called before any of the build/match functions or
+# the generated variables are used.
+
+die if scalar @ARGV != 2;
+
+my $syms = "";
+my $init = "";
+my $initFun = "init";
+
+open HEADER, ">$ARGV[0]";
+open IMPL, ">$ARGV[1]";
+
+while (<STDIN>) {
+ next if (/^\s*$/);
+
+ if (/^\s*(\w*)\s*\|([^\|]*)\|\s*(\w+)\s*\|\s*(\w+)?/) {
+ my $const = $1;
+ my @types = split ' ', $2;
+ my $result = $3;
+ my $funname = $4;
+ $funname = $const unless defined $funname;
+
+ my $formals = "";
+ my $formals2 = "";
+ my $args = "";
+ my $unpack = "";
+ my $n = 1;
+ foreach my $type (@types) {
+ $args .= ", ";
+ if ($type eq "string") {
+# $args .= "(ATerm) ATmakeAppl0(ATmakeAFun((char *) e$n, 0, ATtrue))";
+# $type = "const char *";
+ $type = "ATerm";
+ $args .= "e$n";
+ # !!! in the matcher, we should check that the
+ # argument is a string (i.e., a nullary application).
+ } elsif ($type eq "int") {
+ $args .= "(ATerm) ATmakeInt(e$n)";
+ } elsif ($type eq "ATermList" || $type eq "ATermBlob") {
+ $args .= "(ATerm) e$n";
+ } else {
+ $args .= "e$n";
+ }
+ $formals .= ", " if $formals ne "";
+ $formals .= "$type e$n";
+ $formals2 .= ", ";
+ $formals2 .= "$type & e$n";
+ my $m = $n - 1;
+ # !!! more checks here
+ if ($type eq "int") {
+ $unpack .= " e$n = ATgetInt((ATermInt) ATgetArgument(e, $m));\n";
+ } elsif ($type eq "ATermList") {
+ $unpack .= " e$n = (ATermList) ATgetArgument(e, $m);\n";
+ } elsif ($type eq "ATermBlob") {
+ $unpack .= " e$n = (ATermBlob) ATgetArgument(e, $m);\n";
+ } else {
+ $unpack .= " e$n = ATgetArgument(e, $m);\n";
+ }
+ $n++;
+ }
+
+ my $arity = scalar @types;
+
+ print HEADER "extern AFun sym$funname;\n\n";
+
+ print IMPL "AFun sym$funname = 0;\n";
+
+ print HEADER "static inline $result make$funname($formals) {\n";
+ print HEADER " return (ATerm) ATmakeAppl$arity(sym$funname$args);\n";
+ print HEADER "}\n\n";
+
+ print HEADER "#ifdef __cplusplus\n";
+ print HEADER "static inline bool match$funname(ATerm e$formals2) {\n";
+ print HEADER " if (ATgetType(e) != AT_APPL || ATgetAFun(e) != sym$funname) return false;\n";
+ print HEADER "$unpack";
+ print HEADER " return true;\n";
+ print HEADER "}\n";
+ print HEADER "#endif\n\n\n";
+
+ $init .= " sym$funname = ATmakeAFun(\"$const\", $arity, ATfalse);\n";
+ $init .= " ATprotectAFun(sym$funname);\n";
+ }
+
+ elsif (/^\s*(\w+)\s*=\s*(.*)$/) {
+ my $name = $1;
+ my $value = $2;
+ print HEADER "extern ATerm $name;\n";
+ print IMPL "ATerm $name = 0;\n";
+ $init .= " $name = $value;\n";
+ }
+
+ elsif (/^\s*init\s+(\w+)\s*$/) {
+ $initFun = $1;
+ }
+
+ else {
+ die "bad line: `$_'";
+ }
+}
+
+print HEADER "void $initFun();\n\n";
+
+print HEADER "static inline ATerm string2ATerm(const char * s) {\n";
+print HEADER " return (ATerm) ATmakeAppl0(ATmakeAFun((char *) s, 0, ATtrue));\n";
+print HEADER "}\n\n";
+
+print HEADER "static inline const char * aterm2String(ATerm t) {\n";
+print HEADER " return (const char *) ATgetName(ATgetAFun(t));\n";
+print HEADER "}\n\n";
+
+print IMPL "\n";
+print IMPL "void $initFun() {\n";
+print IMPL "$init";
+print IMPL "}\n";
+
+close HEADER;
+close IMPL;