[llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/treecc/examples/README expr_c.tc expr_cpp.tc expr_cs.tc expr_java.tc expr_ruby.tc

John Criswell criswell at cs.uiuc.edu
Tue Apr 6 12:56:58 PDT 2004


Changes in directory llvm/test/Programs/MultiSource/Applications/treecc/examples:

README added (r1.1)
expr_c.tc added (r1.1)
expr_cpp.tc added (r1.1)
expr_cs.tc added (r1.1)
expr_java.tc added (r1.1)
expr_ruby.tc added (r1.1)

---
Log message:

Committing original README file and treecc example input files.



---
Diffs of the changes:  (+2023 -0)

Index: llvm/test/Programs/MultiSource/Applications/treecc/examples/README
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/examples/README:1.1
*** /dev/null	Tue Apr  6 12:54:27 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/examples/README	Tue Apr  6 12:54:17 2004
***************
*** 0 ****
--- 1,28 ----
+ This directory contains a number of example files of using treecc
+ to implement expression grammars.  The code is more involved than
+ the examples in the Texinfo documentation to give you a better feel
+ for how to use treecc in a realistic setting.
+ 
+ expr_c.tc       Treecc input file for the C version of the example
+ gram_c.y        Yacc input file for the C version of the example
+ scan_c.l        Lex input file for the C version of the example
+ 
+ expr_cpp.tc     Treecc input file for the C++ version of the example
+ gram_cpp.yy     Yacc input file for the C++ version of the example
+ scan_cpp.ll     Lex input file for the C++ version of the example
+ 
+ expr_java.tc    Treecc input file for the Java version of the example
+ eval_value.java Helper class used by the Java version of the example
+ mkjava          Shell script for building the Java version of the example
+ 
+ expr_cs.tc      Treecc input file for the C# version of the example
+ mkcsharp        Shell script for building the C# version of the example
+ 
+ expr_ruby.tc    Treecc input file for the Ruby version of the example
+ 
+ The C++ example demonstrates creating a reentrant system.
+ 
+ The Java and C# versions build and compile, but cannot run because
+ they don't yet have lexing or parsing support.
+ 
+ The Java version is built in a subdirectory called "outjava".


Index: llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_c.tc
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_c.tc:1.1
*** /dev/null	Tue Apr  6 12:54:27 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_c.tc	Tue Apr  6 12:54:17 2004
***************
*** 0 ****
--- 1,447 ----
+ /*
+  * expr_c.tc - Expression example treecc input file for C.
+  *
+  * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+ /*
+  * Include the following declarations into the ".h" file.
+  */
+ %decls %{
+ 
+ /*
+  * Value that is computed by "eval_expr" below.
+  */
+ typedef union
+ {
+ 	int		int_value;
+ 	float	float_value;
+ 
+ } eval_value;
+ 
+ %}
+ 
+ /*
+  * Include the following declarations into the ".c" file.
+  */
+ %{
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <math.h>
+ 
+ #include "expr_c.h"
+ 
+ %}
+ 
+ /*
+  * Define the type code that is associated with a node
+  * in the syntax tree.  We use "error_type" to indicate
+  * a failure during type inferencing.
+  */
+ %enum type_code =
+ {
+ 	error_type,
+     int_type,
+     float_type
+ }
+ 
+ /*
+  * Define the node types that make up the syntax.
+  */
+ %node expression %abstract %typedef =
+ {
+     %nocreate type_code type = {error_type};
+ }
+ 
+ %node binary expression %abstract =
+ {
+     expression *expr1;
+     expression *expr2;
+ }
+ 
+ %node unary expression %abstract =
+ {
+     expression *expr;
+ }
+ 
+ %node intnum expression =
+ {
+     int num;
+ }
+ 
+ %node floatnum expression =
+ {
+     float num;
+ }
+ 
+ %node plus binary
+ %node minus binary
+ %node multiply binary
+ %node divide binary
+ %node power binary
+ %node negate unary
+ 
+ %node cast expression =
+ {
+ 	type_code new_type;
+ 	expression *expr;
+ }
+ 
+ /*
+  * Define the "infer_type" operation as a non-virtual.
+  */
+ %operation void infer_type(expression *e)
+ 
+ infer_type(binary)
+ {
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+     if(e->expr1->type == error_type || e->expr2->type == error_type)
+ 	{
+         e->type = error_type;
+ 	}
+     else if(e->expr1->type == float_type || e->expr2->type == float_type)
+     {
+         e->type = float_type;
+     }
+     else
+     {
+         e->type = int_type;
+     }
+ }
+ 
+ infer_type(unary)
+ {
+     infer_type(e->expr);
+     e->type = e->expr->type;
+ }
+ 
+ infer_type(intnum)
+ {
+     e->type = int_type;
+ }
+ 
+ infer_type(floatnum)
+ {
+     e->type = float_type;
+ }
+ 
+ infer_type(power)
+ {
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+ 	if(e->expr1->type == error_type || e->expr2->type == error_type)
+ 	{
+ 		e->type = error_type;
+ 	}
+     else if(e->expr2->type != int_type)
+     {
+         fprintf(stderr, "%s:%ld: second argument to `^' is not an integer\n",
+                 yygetfilename(e), yygetlinenum(e));
+ 		e->type = error_type;
+     }
+ 	else
+ 	{
+     	e->type = e->expr1->type;
+ 	}
+ }
+ 
+ infer_type(cast)
+ {
+ 	infer_type(e->expr);
+ 
+ 	if(e->expr->type != error_type)
+ 	{
+ 		e->type = e->new_type;
+ 	}
+ 	else
+ 	{
+ 		e->type = error_type;
+ 	}
+ }
+ 
+ /*
+  * Define the "eval_expr" operation as a virtual.
+  */
+ %operation %virtual eval_value eval_expr(expression *e)
+ 
+ eval_expr(plus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = eval_expr(e->expr1);
+ 	eval_value value2 = eval_expr(e->expr2);
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, e->expr1->type, e->type);
+ 	coerce(&value2, e->expr2->type, e->type);
+ 
+ 	/* Evaluate the operator */
+ 	if(e->type == int_type)
+ 	{
+ 		value1.int_value += value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value += value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(minus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = eval_expr(e->expr1);
+ 	eval_value value2 = eval_expr(e->expr2);
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, e->expr1->type, e->type);
+ 	coerce(&value2, e->expr2->type, e->type);
+ 
+ 	/* Evaluate the operator */
+ 	if(e->type == int_type)
+ 	{
+ 		value1.int_value -= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value -= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(multiply)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = eval_expr(e->expr1);
+ 	eval_value value2 = eval_expr(e->expr2);
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, e->expr1->type, e->type);
+ 	coerce(&value2, e->expr2->type, e->type);
+ 
+ 	/* Evaluate the operator */
+ 	if(e->type == int_type)
+ 	{
+ 		value1.int_value *= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value *= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(divide)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = eval_expr(e->expr1);
+ 	eval_value value2 = eval_expr(e->expr2);
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, e->expr1->type, e->type);
+ 	coerce(&value2, e->expr2->type, e->type);
+ 
+ 	/* Evaluate the operator */
+ 	if(e->type == int_type)
+ 	{
+ 		if(value2.int_value != 0)
+ 		{
+ 			value1.int_value /= value2.int_value;
+ 		}
+ 		else
+ 		{
+ 			fprintf(stderr, "%s:%ld: division by zero\n",
+ 					yygetfilename(e), yygetlinenum(e));
+ 			value1.int_value = 0;
+ 		}
+ 	}
+ 	else
+ 	{
+ 		value1.float_value /= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(power)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = eval_expr(e->expr1);
+ 	eval_value value2 = eval_expr(e->expr2);
+ 
+ 	/* Evaluate the operator */
+ 	if(e->type == int_type)
+ 	{
+ 		value1.int_value = (int)(pow((double)(value1.int_value),
+ 		                             (double)(value2.int_value)));
+ 	}
+ 	else
+ 	{
+ 		value1.float_value = (float)(pow((double)(value1.float_value),
+ 		                                 (double)(value2.int_value)));
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(negate)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = eval_expr(e->expr);
+ 
+ 	/* Evaluate the operator */
+ 	if(e->type == int_type)
+ 	{
+ 		value.int_value = -(value.int_value);
+ 	}
+ 	else
+ 	{
+ 		value.float_value = -(value.float_value);
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(cast)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = eval_expr(e->expr);
+ 
+ 	/* Cast to the final type */
+ 	coerce(&value, e->expr->type, e->type);
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(intnum)
+ {
+ 	eval_value value;
+ 	value.int_value = e->num;
+ 	return value;
+ }
+ 
+ eval_expr(floatnum)
+ {
+ 	eval_value value;
+ 	value.float_value = e->num;
+ 	return value;
+ }
+ 
+ /*
+  * Define the "coerce" operation as an inline non-virtual.
+  */
+ %operation %inline void coerce
+ 				(eval_value *value, [type_code from], [type_code to])
+ 
+ coerce(int_type, float_type)
+ {
+ 	value->float_value = (float)(value->int_value);
+ }
+ 
+ coerce(float_type, int_type)
+ {
+ 	value->int_value = (int)(value->float_value);
+ }
+ 
+ coerce(type_code, type_code)
+ {
+ 	/* Nothing to do here */
+ }
+ 
+ /*
+  * Include the following code at the end of the ".c" file.
+  */
+ %end %{
+ 
+ /*
+  * Global data used by the expression parser.
+  */
+ char *progname;
+ char *filename;
+ long linenum;
+ 
+ /*
+  * Entry points that are imported from the yacc parser.
+  */
+ extern void yyrestart(FILE *file);
+ extern int yyparse(void);
+ 
+ /*
+  * Main entry point for the expression parser and evaluator.
+  */
+ int main(int argc, char *argv[])
+ {
+ 	FILE *file;
+ 	progname = argv[0];
+ 	linenum = 1;
+ 	if(argc < 2)
+ 	{
+ 		filename = "stdin";
+ 		yyrestart(stdin);
+ 	}
+ 	else if((file = fopen(argv[1], "r")) == NULL)
+ 	{
+ 		perror(argv[1]);
+ 		return 1;
+ 	}
+ 	else
+ 	{
+ 		filename = argv[1];
+ 		yyrestart(file);
+ 	}
+ 	return yyparse();
+ }
+ 
+ /*
+  * Get the name of the current input file in use by the parser.
+  */
+ char *yycurrfilename(void)
+ {
+ 	return filename;
+ }
+ 
+ /*
+  * Get the line number for the current input line in use by the parser.
+  */
+ long yycurrlinenum(void)
+ {
+ 	return linenum;
+ }
+ 
+ /*
+  * Report memory failure and exit.
+  */
+ void yynodefailed(void)
+ {
+ 	fputs(progname, stderr);
+ 	fputs(": virtual memory exhausted\n", stderr);
+ 	exit(1);
+ }
+ 
+ %}


Index: llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_cpp.tc
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_cpp.tc:1.1
*** /dev/null	Tue Apr  6 12:54:27 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_cpp.tc	Tue Apr  6 12:54:17 2004
***************
*** 0 ****
--- 1,502 ----
+ /*
+  * expr_cpp.tc - Expression example treecc input file for C++.
+  *
+  * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+ %option lang = "C++"
+ %option reentrant
+ 
+ %header "expr_cpp.h"
+ %output "expr_cpp.cc"
+ 
+ /*
+  * Include the following declarations into the ".h" file.
+  */
+ %decls %{
+ 
+ /*
+  * Value that is computed by "eval_expr" below.
+  */
+ typedef union
+ {
+ 	int		int_value;
+ 	float	float_value;
+ 
+ } eval_value;
+ 
+ %}
+ 
+ /*
+  * Include the following declarations into the ".cc" file.
+  */
+ %{
+ #include <iostream.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <math.h>
+ 
+ #include "expr_cpp.h"
+ 
+ %}
+ 
+ /*
+  * Define the type code that is associated with a node
+  * in the syntax tree.  We use "error_type" to indicate
+  * a failure during type inferencing.
+  */
+ %enum type_code =
+ {
+ 	error_type,
+     int_type,
+     float_type
+ }
+ 
+ /*
+  * Define the node types that make up the syntax.
+  */
+ %node expression %abstract %typedef =
+ {
+     %nocreate type_code type = {error_type};
+ }
+ 
+ %node binary expression %abstract =
+ {
+     expression *expr1;
+     expression *expr2;
+ }
+ 
+ %node unary expression %abstract =
+ {
+     expression *expr;
+ }
+ 
+ %node intnum expression =
+ {
+     int num;
+ }
+ 
+ %node floatnum expression =
+ {
+     float num;
+ }
+ 
+ %node plus binary
+ %node minus binary
+ %node multiply binary
+ %node divide binary
+ %node power binary
+ %node negate unary
+ 
+ %node cast expression =
+ {
+ 	type_code new_type;
+ 	expression *expr;
+ }
+ 
+ /*
+  * Define the "infer_type" operation as a non-virtual.
+  */
+ %operation void infer_type(expression *e)
+ 
+ infer_type(binary)
+ {
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+     if(e->expr1->type == error_type || e->expr2->type == error_type)
+ 	{
+         e->type = error_type;
+ 	}
+     else if(e->expr1->type == float_type || e->expr2->type == float_type)
+     {
+         e->type = float_type;
+     }
+     else
+     {
+         e->type = int_type;
+     }
+ }
+ 
+ infer_type(unary)
+ {
+     infer_type(e->expr);
+     e->type = e->expr->type;
+ }
+ 
+ infer_type(intnum)
+ {
+     e->type = int_type;
+ }
+ 
+ infer_type(floatnum)
+ {
+     e->type = float_type;
+ }
+ 
+ infer_type(power)
+ {
+     infer_type(e->expr1);
+     infer_type(e->expr2);
+ 
+ 	if(e->expr1->type == error_type || e->expr2->type == error_type)
+ 	{
+ 		e->type = error_type;
+ 	}
+     else if(e->expr2->type != int_type)
+     {
+ 		cerr << e->getFilename() << ":" << e->getLinenum() <<
+         		": second argument to `^' is not an integer" << endl;
+ 		e->type = error_type;
+     }
+ 	else
+ 	{
+     	e->type = e->expr1->type;
+ 	}
+ }
+ 
+ infer_type(cast)
+ {
+ 	infer_type(e->expr);
+ 
+ 	if(e->expr->type != error_type)
+ 	{
+ 		e->type = e->new_type;
+ 	}
+ 	else
+ 	{
+ 		e->type = error_type;
+ 	}
+ }
+ 
+ /*
+  * Define the "eval_expr" operation as a virtual.
+  */
+ %operation %virtual eval_value eval_expr(expression *this)
+ 
+ eval_expr(plus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1->eval_expr();
+ 	eval_value value2 = expr2->eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, expr1->type, type);
+ 	coerce(&value2, expr2->type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == int_type)
+ 	{
+ 		value1.int_value += value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value += value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(minus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1->eval_expr();
+ 	eval_value value2 = expr2->eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, expr1->type, type);
+ 	coerce(&value2, expr2->type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == int_type)
+ 	{
+ 		value1.int_value -= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value -= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(multiply)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1->eval_expr();
+ 	eval_value value2 = expr2->eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, expr1->type, type);
+ 	coerce(&value2, expr2->type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == int_type)
+ 	{
+ 		value1.int_value *= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value *= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(divide)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1->eval_expr();
+ 	eval_value value2 = expr2->eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce(&value1, expr1->type, type);
+ 	coerce(&value2, expr2->type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == int_type)
+ 	{
+ 		if(value2.int_value != 0)
+ 		{
+ 			value1.int_value /= value2.int_value;
+ 		}
+ 		else
+ 		{
+ 			cerr << getFilename() << ":" << getLinenum() <<
+ 					": division by zero" << endl;
+ 			value1.int_value = 0;
+ 		}
+ 	}
+ 	else
+ 	{
+ 		value1.float_value /= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(power)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1->eval_expr();
+ 	eval_value value2 = expr2->eval_expr();
+ 
+ 	/* Evaluate the operator */
+ 	if(type == int_type)
+ 	{
+ 		value1.int_value = (int)(pow((double)(value1.int_value),
+ 		                             (double)(value2.int_value)));
+ 	}
+ 	else
+ 	{
+ 		value1.float_value = (float)(pow((double)(value1.float_value),
+ 		                                 (double)(value2.int_value)));
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(negate)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = expr->eval_expr();
+ 
+ 	/* Evaluate the operator */
+ 	if(type == int_type)
+ 	{
+ 		value.int_value = -(value.int_value);
+ 	}
+ 	else
+ 	{
+ 		value.float_value = -(value.float_value);
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(cast)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = expr->eval_expr();
+ 
+ 	/* Cast to the final type */
+ 	coerce(&value, expr->type, type);
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(intnum)
+ {
+ 	eval_value value;
+ 	value.int_value = num;
+ 	return value;
+ }
+ 
+ eval_expr(floatnum)
+ {
+ 	eval_value value;
+ 	value.float_value = num;
+ 	return value;
+ }
+ 
+ /*
+  * Define the "coerce" operation as an inline non-virtual.
+  */
+ %operation %inline void coerce
+ 				(eval_value *value, [type_code from], [type_code to])
+ 
+ coerce(int_type, float_type)
+ {
+ 	value->float_value = (float)(value->int_value);
+ }
+ 
+ coerce(float_type, int_type)
+ {
+ 	value->int_value = (int)(value->float_value);
+ }
+ 
+ coerce(type_code, type_code)
+ {
+ 	/* Nothing to do here */
+ }
+ 
+ /*
+  * Include the following code at the end of the ".h" file.
+  */
+ %end %decls %{
+ 
+ /*
+  * Inherit YYNODESTATE to provide additional functionality.
+  */
+ class NodeState : public YYNODESTATE
+ {
+ private:
+ 
+ 	char *progname;
+ 	char *filename;
+ 	long  linenum;
+ 
+ public:
+ 
+ 	NodeState(char *_progname, char *_filename)
+ 			: YYNODESTATE()
+ 		{
+ 			filename = _filename;
+ 			linenum = 1;
+ 		}
+ 	virtual ~NodeState();
+ 
+ public:
+ 
+ 	virtual char *currFilename();
+ 	virtual long currLinenum();
+ 	virtual void failed();
+ 
+ 	void incLine() { ++linenum; }
+ 
+ };
+ 
+ %}
+ 
+ /*
+  * Include the following code at the end of the ".cc" file.
+  */
+ %end %{
+ 
+ /*
+  * Entry points that are imported from the yacc parser.
+  */
+ extern void yyrestart(FILE *file);
+ extern int yyparse(void *);
+ 
+ /*
+  * Main entry point for the expression parser and evaluator.
+  */
+ int main(int argc, char *argv[])
+ {
+ 	FILE *file;
+ 	char *filename;
+ 	int retval;
+ 
+ 	/* Parse the command-line arguments and open the input file */
+ 	if(argc < 2)
+ 	{
+ 		filename = "stdin";
+ 		file = stdin;
+ 	}
+ 	else if((file = fopen(argv[1], "r")) == NULL)
+ 	{
+ 		perror(argv[1]);
+ 		return 1;
+ 	}
+ 	else
+ 	{
+ 		filename = argv[1];
+ 	}
+ 
+ 	/* Create the node factory and state object */
+ 	NodeState *state = new NodeState(argv[0], filename);
+ 
+ 	/* Parse and evaluate the expressions in the input */
+ 	retval = yyparse(state);
+ 
+ 	/* Clean up and exit */
+ 	delete state;
+ 	return retval;
+ }
+ 
+ /*
+  * Destructor for NodeState.
+  */
+ NodeState::~NodeState()
+ {
+ 	/* Nothing needs to be done here */
+ }
+ 
+ /*
+  * Get the name of the current input file in use by the parser.
+  */
+ char *NodeState::currFilename()
+ {
+ 	return filename;
+ }
+ 
+ /*
+  * Get the line number for the current input line in use by the parser.
+  */
+ long NodeState::currLinenum()
+ {
+ 	return linenum;
+ }
+ 
+ /*
+  * Report memory failure and exit.
+  */
+ void NodeState::failed()
+ {
+ 	cerr << progname << ": virtual memory exhausted" << endl;
+ 	exit(1);
+ }
+ 
+ %}


Index: llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_cs.tc
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_cs.tc:1.1
*** /dev/null	Tue Apr  6 12:54:27 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_cs.tc	Tue Apr  6 12:54:17 2004
***************
*** 0 ****
--- 1,366 ----
+ /*
+  * expr_cs.tc - Expression example treecc input file for C#.
+  *
+  * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+ %option lang = "C#"
+ 
+ %output "expr_cs.cs"
+ 
+ /*
+  * Include the following declarations in the ".cs" file.
+  */
+ %{
+ 
+ public class eval_value
+ {
+ 	public int int_value;
+ 	public float float_value;
+ }
+ 
+ %}
+ 
+ /*
+  * Define the type code that is associated with a node
+  * in the syntax tree.  We use "error_type" to indicate
+  * a failure during type inferencing.
+  */
+ %enum type_code =
+ {
+ 	error_type,
+     int_type,
+     float_type
+ }
+ 
+ /*
+  * Define the node types that make up the syntax.
+  */
+ %node expression %abstract %typedef =
+ {
+     %nocreate type_code type = {type_code.error_type};
+ }
+ 
+ %node binary expression %abstract =
+ {
+     expression expr1;
+     expression expr2;
+ }
+ 
+ %node unary expression %abstract =
+ {
+     expression expr;
+ }
+ 
+ %node intnum expression =
+ {
+     int num;
+ }
+ 
+ %node floatnum expression =
+ {
+     float num;
+ }
+ 
+ %node plus binary
+ %node minus binary
+ %node multiply binary
+ %node divide binary
+ %node power binary
+ %node negate unary
+ 
+ %node cast expression =
+ {
+ 	type_code new_type;
+ 	expression expr;
+ }
+ 
+ /*
+  * Define the "infer_type" operation as a non-virtual.
+  */
+ %operation void InferType::infer_type(expression e)
+ 
+ infer_type(binary)
+ {
+     infer_type(e.expr1);
+     infer_type(e.expr2);
+ 
+     if(e.expr1.type == type_code.error_type ||
+ 	   e.expr2.type == type_code.error_type)
+ 	{
+         e.type = type_code.error_type;
+ 	}
+     else if(e.expr1.type == type_code.float_type ||
+ 		    e.expr2.type == type_code.float_type)
+     {
+         e.type = type_code.float_type;
+     }
+     else
+     {
+         e.type = type_code.int_type;
+     }
+ }
+ 
+ infer_type(unary)
+ {
+     infer_type(e.expr);
+     e.type = e.expr.type;
+ }
+ 
+ infer_type(intnum)
+ {
+     e.type = type_code.int_type;
+ }
+ 
+ infer_type(floatnum)
+ {
+     e.type = type_code.float_type;
+ }
+ 
+ infer_type(power)
+ {
+     infer_type(e.expr1);
+     infer_type(e.expr2);
+ 
+ 	if(e.expr1.type == type_code.error_type ||
+ 	   e.expr2.type == type_code.error_type)
+ 	{
+ 		e.type = type_code.error_type;
+ 	}
+     else if(e.expr2.type != type_code.int_type)
+     {
+ 		Console.Error.WriteLine(e.getFilename() + ":" + e.getLinenum() +
+         				        ": second argument to `^' is not an integer");
+ 		e.type = type_code.error_type;
+     }
+ 	else
+ 	{
+     	e.type = e.expr1.type;
+ 	}
+ }
+ 
+ infer_type(cast)
+ {
+ 	infer_type(e.expr);
+ 
+ 	if(e.expr.type != type_code.error_type)
+ 	{
+ 		e.type = e.new_type;
+ 	}
+ 	else
+ 	{
+ 		e.type = type_code.error_type;
+ 	}
+ }
+ 
+ /*
+  * Define the "eval_expr" operation as a virtual.
+  */
+ %operation %virtual eval_value eval_expr(expression *this)
+ 
+ eval_expr(plus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	Coerce.coerce(value1, expr1.type, type);
+ 	Coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value += value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value += value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(minus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	Coerce.coerce(value1, expr1.type, type);
+ 	Coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value -= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value -= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(multiply)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	Coerce.coerce(value1, expr1.type, type);
+ 	Coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value *= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value *= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(divide)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	Coerce.coerce(value1, expr1.type, type);
+ 	Coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		if(value2.int_value != 0)
+ 		{
+ 			value1.int_value /= value2.int_value;
+ 		}
+ 		else
+ 		{
+ 			Console.Error.WriteLine(getFilename() + ":" + getLinenum() +
+ 							        ": division by zero");
+ 			value1.int_value = 0;
+ 		}
+ 	}
+ 	else
+ 	{
+ 		value1.float_value /= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(power)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value = (int)(Math.Pow((double)(value1.int_value),
+ 		                                  (double)(value2.int_value)));
+ 	}
+ 	else
+ 	{
+ 		value1.float_value = (float)(Math.Pow((double)(value1.float_value),
+ 		                                      (double)(value2.int_value)));
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(negate)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = expr.eval_expr();
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value.int_value = -(value.int_value);
+ 	}
+ 	else
+ 	{
+ 		value.float_value = -(value.float_value);
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(cast)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = expr.eval_expr();
+ 
+ 	/* Cast to the final type */
+ 	Coerce.coerce(value, expr.type, type);
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(intnum)
+ {
+ 	eval_value value = new eval_value();
+ 	value.int_value = num;
+ 	return value;
+ }
+ 
+ eval_expr(floatnum)
+ {
+ 	eval_value value = new eval_value();
+ 	value.float_value = num;
+ 	return value;
+ }
+ 
+ /*
+  * Define the "coerce" operation as an inline non-virtual.
+  */
+ %operation %inline void Coerce::coerce
+ 				(eval_value value, [type_code from], [type_code to])
+ 
+ coerce(int_type, float_type)
+ {
+ 	value.float_value = (float)(value.int_value);
+ }
+ 
+ coerce(float_type, int_type)
+ {
+ 	value.int_value = (int)(value.float_value);
+ }
+ 
+ coerce(type_code, type_code)
+ {
+ 	/* Nothing to do here */
+ }


Index: llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_java.tc
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_java.tc:1.1
*** /dev/null	Tue Apr  6 12:54:27 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_java.tc	Tue Apr  6 12:54:17 2004
***************
*** 0 ****
--- 1,351 ----
+ /*
+  * expr_java.tc - Expression example treecc input file for Java.
+  *
+  * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+ %option lang = "Java"
+ 
+ /*
+  * Define the type code that is associated with a node
+  * in the syntax tree.  We use "error_type" to indicate
+  * a failure during type inferencing.
+  */
+ %enum type_code =
+ {
+ 	error_type,
+     int_type,
+     float_type
+ }
+ 
+ /*
+  * Define the node types that make up the syntax.
+  */
+ %node expression %abstract %typedef =
+ {
+     %nocreate type_code type = {type_code.error_type};
+ }
+ 
+ %node binary expression %abstract =
+ {
+     expression expr1;
+     expression expr2;
+ }
+ 
+ %node unary expression %abstract =
+ {
+     expression expr;
+ }
+ 
+ %node intnum expression =
+ {
+     int num;
+ }
+ 
+ %node floatnum expression =
+ {
+     float num;
+ }
+ 
+ %node plus binary
+ %node minus binary
+ %node multiply binary
+ %node divide binary
+ %node power binary
+ %node negate unary
+ 
+ %node cast expression =
+ {
+ 	type_code new_type;
+ 	expression expr;
+ }
+ 
+ /*
+  * Define the "infer_type" operation as a non-virtual.
+  */
+ %operation void infer_type(expression e)
+ 
+ infer_type(binary)
+ {
+     infer_type(e.expr1);
+     infer_type(e.expr2);
+ 
+     if(e.expr1.type == type_code.error_type ||
+ 	   e.expr2.type == type_code.error_type)
+ 	{
+         e.type = type_code.error_type;
+ 	}
+     else if(e.expr1.type == type_code.float_type ||
+ 		    e.expr2.type == type_code.float_type)
+     {
+         e.type = type_code.float_type;
+     }
+     else
+     {
+         e.type = type_code.int_type;
+     }
+ }
+ 
+ infer_type(unary)
+ {
+     infer_type(e.expr);
+     e.type = e.expr.type;
+ }
+ 
+ infer_type(intnum)
+ {
+     e.type = type_code.int_type;
+ }
+ 
+ infer_type(floatnum)
+ {
+     e.type = type_code.float_type;
+ }
+ 
+ infer_type(power)
+ {
+     infer_type(e.expr1);
+     infer_type(e.expr2);
+ 
+ 	if(e.expr1.type == type_code.error_type ||
+ 	   e.expr2.type == type_code.error_type)
+ 	{
+ 		e.type = type_code.error_type;
+ 	}
+     else if(e.expr2.type != type_code.int_type)
+     {
+ 		System.err.println(e.getFilename() + ":" + e.getLinenum() +
+         				   ": second argument to `^' is not an integer");
+ 		e.type = type_code.error_type;
+     }
+ 	else
+ 	{
+     	e.type = e.expr1.type;
+ 	}
+ }
+ 
+ infer_type(cast)
+ {
+ 	infer_type(e.expr);
+ 
+ 	if(e.expr.type != type_code.error_type)
+ 	{
+ 		e.type = e.new_type;
+ 	}
+ 	else
+ 	{
+ 		e.type = type_code.error_type;
+ 	}
+ }
+ 
+ /*
+  * Define the "eval_expr" operation as a virtual.
+  */
+ %operation %virtual eval_value eval_expr(expression *this)
+ 
+ eval_expr(plus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce.coerce(value1, expr1.type, type);
+ 	coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value += value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value += value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(minus)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce.coerce(value1, expr1.type, type);
+ 	coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value -= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value -= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(multiply)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce.coerce(value1, expr1.type, type);
+ 	coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value *= value2.int_value;
+ 	}
+ 	else
+ 	{
+ 		value1.float_value *= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(divide)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Coerce to the common type */
+ 	coerce.coerce(value1, expr1.type, type);
+ 	coerce.coerce(value2, expr2.type, type);
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		if(value2.int_value != 0)
+ 		{
+ 			value1.int_value /= value2.int_value;
+ 		}
+ 		else
+ 		{
+ 			System.err.println(getFilename() + ":" + getLinenum() +
+ 							   ": division by zero");
+ 			value1.int_value = 0;
+ 		}
+ 	}
+ 	else
+ 	{
+ 		value1.float_value /= value2.float_value;
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(power)
+ {
+ 	/* Evaluate the sub-expressions */
+ 	eval_value value1 = expr1.eval_expr();
+ 	eval_value value2 = expr2.eval_expr();
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value1.int_value = (int)(Math.pow((double)(value1.int_value),
+ 		                                  (double)(value2.int_value)));
+ 	}
+ 	else
+ 	{
+ 		value1.float_value = (float)(Math.pow((double)(value1.float_value),
+ 		                                      (double)(value2.int_value)));
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value1;
+ }
+ 
+ eval_expr(negate)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = expr.eval_expr();
+ 
+ 	/* Evaluate the operator */
+ 	if(type == type_code.int_type)
+ 	{
+ 		value.int_value = -(value.int_value);
+ 	}
+ 	else
+ 	{
+ 		value.float_value = -(value.float_value);
+ 	}
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(cast)
+ {
+ 	/* Evaluate the sub-expression */
+ 	eval_value value = expr.eval_expr();
+ 
+ 	/* Cast to the final type */
+ 	coerce.coerce(value, expr.type, type);
+ 
+ 	/* Return the result to the caller */
+ 	return value;
+ }
+ 
+ eval_expr(intnum)
+ {
+ 	eval_value value = new eval_value();
+ 	value.int_value = num;
+ 	return value;
+ }
+ 
+ eval_expr(floatnum)
+ {
+ 	eval_value value = new eval_value();
+ 	value.float_value = num;
+ 	return value;
+ }
+ 
+ /*
+  * Define the "coerce" operation as an inline non-virtual.
+  */
+ %operation %inline void coerce
+ 				(eval_value value, [type_code from], [type_code to])
+ 
+ coerce(int_type, float_type)
+ {
+ 	value.float_value = (float)(value.int_value);
+ }
+ 
+ coerce(float_type, int_type)
+ {
+ 	value.int_value = (int)(value.float_value);
+ }
+ 
+ coerce(type_code, type_code)
+ {
+ 	/* Nothing to do here */
+ }


Index: llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_ruby.tc
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_ruby.tc:1.1
*** /dev/null	Tue Apr  6 12:54:27 2004
--- llvm/test/Programs/MultiSource/Applications/treecc/examples/expr_ruby.tc	Tue Apr  6 12:54:17 2004
***************
*** 0 ****
--- 1,329 ----
+ /*
+  * expr_ruby.tc - Expression example treecc input file for Ruby.
+  *
+  * Copyright (C) 2001, 2002  Southern Storm Software, Pty Ltd.
+  *
+  * Hacked by Peter Minten <silvernerd at users.sf.net>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+ %option lang = "Ruby"
+ 
+ %output "expr_ruby.rb"
+ 
+ /*
+  * Include the following declarations in the ".rb" file.
+  */
+ %{
+ 
+ class Eval_value
+   Int_value = 0
+   Float_value = 0
+ end
+ 
+ %}
+ 
+ /*
+  * Define the type code that is associated with a node
+  * in the syntax tree.  We use "error_type" to indicate
+  * a failure during type inferencing.
+  */
+ %enum Type_code =
+ {
+ 	Error_type,
+     Int_type,
+     Float_type
+ }
+ 
+ /*
+  * Define the node types that make up the syntax.
+  */
+ %node Expression %abstract %typedef =
+ {
+     %nocreate Type_code type = {Type_code::Error_type};
+ }
+ 
+ %node Binary Expression %abstract =
+ {
+     Expression expr1;
+     Expression expr2;
+ }
+ 
+ %node Unary Expression %abstract =
+ {
+     Expression expr;
+ }
+ 
+ %node Intnum Expression =
+ {
+ 	int num;
+ }
+ 
+ %node Floatnum Expression =
+ {
+     float num;
+ }
+ 
+ %node Plus Binary
+ %node Minus Binary
+ %node Multiply Binary
+ %node Divide Binary
+ %node Power Binary
+ %node Negate Unary
+ 
+ %node Cast Expression =
+ {
+ 	Type_code new_type;
+ 	Expression expr;
+ }
+ 
+ /*
+  * Define the "infer_type" operation as a non-virtual.
+  */
+ %operation void InferType::infer_type(Expression e)
+ 
+ infer_type(Binary)
+ {
+   infer_type(e.expr1)
+   infer_type(e.expr2)
+ 
+   if (e.expr1.type == Type_code::Error_type || e.expr2.type == Type_code::Error_type) then
+     e.type = Type_code::Error_type
+   elsif (e.expr1.type == Type_code::Float_type || e.expr2.type == Type_code::Float_type) then
+     e.type = Type_code::Float_type
+   else
+     e.type = Type_code::Int_type
+   end
+ }
+ 
+ infer_type(Unary)
+ {
+   infer_type(e.expr)
+   e.type = e.expr.type
+ }
+ 
+ infer_type(Intnum)
+ {
+   e.type = Type_code::Int_type
+ }
+ 
+ infer_type(Floatnum)
+ {
+   e.type = Type_code::Float_type
+ }
+ 
+ infer_type(Power)
+ {
+   infer_type(e.expr1)
+   infer_type(e.expr2)
+ 
+   if (e.expr1.type == Type_code::Error_type || e.expr2.type == Type_code::Error_type) then
+     e.type = Type_code::Error_type
+   elsif (e.expr2.type != Type_code::Int_type) then
+     p (e.getFilename() + ":" + e.getLinenum() + ": second argument to `^' is not an integer")
+     e.type = Type_code::Error_type
+   else
+     e.type = e.expr1.type
+   end
+ }
+ 
+ infer_type(Cast)
+ {
+   infer_type(e.expr)
+ 
+   if(e.expr.type != Type_code::Error_type)
+     e.type = e.new_type
+   else
+     e.type = Type_code::Error_type
+   end
+ }
+ 
+ /*
+  * Define the "eval_expr" operation as a virtual.
+  */
+ %operation %virtual eval_value eval_expr(Expression this)
+ 
+ eval_expr(Plus)
+ {
+   # Evaluate the sub-Expressions
+   eval_value value1 = expr1.eval_expr
+   eval_value value2 = expr2.eval_expr
+ 
+   # Coerce to the common type
+   Coerce.coerce(value1, expr1.type, type)
+   Coerce.coerce(value2, expr2.type, type)
+ 
+   # Evaluate the operator 
+   if (type == Type_code::Int_type) then
+     value1.Int_value += value2.Int_value
+   else
+     value1.Float_value += value2.Float_value
+   end
+ 
+   # Return the result to the caller
+   return value1
+ }
+ 
+ eval_expr(Minus)
+ {
+   # Evaluate the sub-Expressions 
+   eval_value value1 = expr1.eval_expr()
+   eval_value value2 = expr2.eval_expr()
+ 
+   # Coerce to the common type
+   Coerce.coerce(value1, expr1.type, type)
+   Coerce.coerce(value2, expr2.type, type)
+ 
+   # Evaluate the operator
+   if(type == Type_code::Int_type) then
+     value1.Int_value -= value2.Int_value
+   else
+     value1.Float_value -= value2.Float_value;
+   end
+ 
+   # Return the result to the caller
+   return value1
+ }
+ 
+ eval_expr(Multiply)
+ {
+   # Evaluate the sub-Expressions 
+   eval_value value1 = expr1.eval_expr()
+   eval_value value2 = expr2.eval_expr()
+ 
+   # Coerce to the common type
+   Coerce.coerce(value1, expr1.type, type)
+   Coerce.coerce(value2, expr2.type, type)
+ 
+   # Evaluate the operator
+   if(type == Type_code::Int_type) then
+     value1.Int_value *= value2.Int_value
+   else
+     value1.Float_value *= value2.Float_value;
+   end
+ 
+   # Return the result to the caller
+   return value1
+ }
+ 
+ eval_expr(Divide)
+ {
+   # Evaluate the sub-Expressions 
+   eval_value value1 = expr1.eval_expr()
+   eval_value value2 = expr2.eval_expr()
+ 
+   # Coerce to the common type
+   Coerce.coerce(value1, expr1.type, type)
+   Coerce.coerce(value2, expr2.type, type)
+ 
+   # Evaluate the operator
+   if(type == Type_code::Int_type) then
+     value1.Int_value -= value2.Int_value
+   else
+     value1.Float_value -= value2.Float_value;
+   end
+ 
+   # Return the result to the caller
+   return value1
+ }
+ 
+ eval_expr(Power)
+ {
+   # Evaluate the sub-Expressions 
+   eval_value value1 = expr1.eval_expr()
+   eval_value value2 = expr2.eval_expr()
+ 
+   # Coerce to the common type
+   Coerce.coerce(value1, expr1.type, type)
+   Coerce.coerce(value2, expr2.type, type)
+ 
+   # Evaluate the operator
+   if(type == Type_code::Int_type) then
+     value1.Int_value = value1.Int_value ^ value2.Int_value
+   else
+     value1.Float_value = value1.Float_value ^ value2.Float_value;
+   end
+ 
+   # Return the result to the caller
+   return value1
+ }
+ 
+ eval_expr(Negate)
+ {
+   # Evaluate the sub-Expression 
+   eval_value value = expr.eval_expr()
+ 
+   # Coerce to the common type
+   Coerce.coerce(value1, expr1.type, type)
+   Coerce.coerce(value, expr.type, type)
+ 
+   # Evaluate the operator
+   if(type == Type_code::Int_type) then
+     value.Int_value = -1 * value.Int_value
+   else
+     value.Float_value = -1 * value.Float_value;
+   end
+ 
+   # Return the result to the caller
+   return value
+ }
+ 
+ eval_expr(Cast)
+ {
+   # Evaluate the sub-Expression
+   eval_value value = expr.eval_expr()
+ 
+   # Coerce to the common type
+   Coerce.coerce(value, expr.type, type)
+ 
+   # Return the result to the caller
+   return value
+ }
+ 
+ eval_expr(Intnum)
+ {
+   value = eval_value.new
+   value.Int_value = num
+   return value
+ }
+ 
+ eval_expr(Floatnum)
+ {
+   value = eval_value.new
+   value.Float_value = num
+   return value
+ }
+ 
+ /*
+  * Define the "coerce" operation as an inline non-virtual.
+  */
+ %operation %inline void Coerce::coerce
+ 				(value, [Type_code from], [Type_code to])
+ 
+ coerce(Int_type, Float_type)
+ {
+   value.Float_value = value.Int_value.to_f;
+ }
+ 
+ coerce(Float_type, Int_type)
+ {
+   value.Int_value = value.Float_value.to_i;
+ }
+ 
+ coerce(Type_code, Type_code)
+ {
+   # Nothing to do here
+ }





More information about the llvm-commits mailing list