m4-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: interpreters/compilers in m4?


From: Johnicholas Hines
Subject: Re: interpreters/compilers in m4?
Date: Mon, 8 Aug 2011 08:51:25 -0400

I'd be interested in an interactive shell also - but rather than a
code generator, I was imagining implementing another language IN m4,
just as you can write a lisp interpreter in C.

Here's a snippet - I made it as small and simple as possible, possibly
too small and simple, but extending it to have variables that are
looked up in the environment, more control flow, should be
straightforward.

divert(-1)
# a global counter used for making things unique
define(`_gensym',`0')
define(`gensym',`_gensym`'define(`_gensym',incr(_gensym))')
# exp ::= Num( int )
define(`_num',`define(`eat_Num'$1,`$'`1_num($2,shift($'`@))')Num$1')
define(`num',`_num(gensym,$1)')
# exp ::= Plus( exp , exp )
define(`_plus',`define(`eat_Plus'$1,`$'`1_plus($2,$3,shift($'`@))')Plus$1')
define(`plus',`_plus(gensym,$1,$2)')
# define print_exp by cases
#   print_exp(Num(int)) => int
define(`_print_exp_num',`$1')
#   print_exp(Plus(exp1,exp2)) => print_exp(exp1)+print_exp(exp2)
define(`_print_exp_plus',`print_exp($1)+print_exp($2)')
# actually dispatch
define(`print_exp',`eat_$1(_print_exp)')
# define my_eval by cases
#   my_eval(Num(int)) => int
define(`_my_eval_num',`$1')
#   my_eval(Plus(exp1,exp2)) => eval(my_eval(exp1)+my_eval(exp2))
define(`_my_eval_plus',`eval(my_eval($1)+my_eval($2))')
# actually dispatch
define(`my_eval',`eat_$1(_my_eval)')
divert`'dnl
# Now we can use the new "little language"
print_exp(plus(plus(num(1),num(2)),num(3)))
my_eval(plus(num(4),plus(num(5),num(6))))

Is this sort of definition-by-cases a standard m4 idiom?
What would the idiomatic way to create a new abstract datatype be?

Johnicholas



reply via email to

[Prev in Thread] Current Thread [Next in Thread]