mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
%{
/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@hom.net
MUD++ development mailing list    mudpp-list@mailhost.net
------------------------------------------------------------------------------
yacc.y
Compiler grammar for MUDC
Compiles to intermediate MUDAsm (see docs/vm)
*/

#include "sym.h"
#include "parse.h"
extern sym * sym_tab[];
extern char yytext[];
char id[ 256 ];
long line;
%}

%union {
	long	lval;
	float	fval;
	char *	sval;
	sym *	sym_ptr;
	node *	node_ptr;
}

%type <lval> type_specifier
%type <node_ptr> declaration
%type <sym_ptr> declarator
%type <sym_ptr> init_declarator
%type <sym_ptr> init_declarator_list
%type <node_ptr> declaration_list
%type <sym_ptr> parameter_type_list
%type <sym_ptr> parameter_declaration
%type <node_ptr> statement 
%type <node_ptr> statement_list 
%type <node_ptr> compound_statement 
%type <node_ptr> jump_statement
%type <node_ptr> function_call 
%type <node_ptr> function_def
%type <node_ptr> primary_expression 
%type <node_ptr> assignment_expression 
%type <node_ptr> postfix_expression 
%type <node_ptr> unary_expression 
%token <sym_ptr> ID
%token <lval> CONSTANT_INT
%token <fval> CONSTANT_FLOAT
%token <sval> STRING_LITERAL
%token DEC_OP INC_OP
%token VOID INT STRING
%token RETURN

%start unit
%%

unit:
		function_def		{}
	|	unit function_def 	{}
	;

declarator:
		ID				{	$$ = $1; }
	|	ID '(' ')'		{	$$ = $1; }
	|	ID '(' parameter_type_list ')'		{	$$ = $1; $$->next = $3; }
	;

type_specifier:
		VOID		{ $$ = TYPE_VOID; }
	|	INT			{ $$ = TYPE_INT; }
	|	STRING		{ $$ = TYPE_STRING; }
	;

declaration:
		type_specifier init_declarator_list ';'
				{
					/* $1 = lval (int), $2 = sym_ptr (symbol *) */
					node * id = mkleaf_declaration( $1, $2 );
					$$ = id;
					printf( "declaration\n" );
				}
	;

init_declarator_list:
		init_declarator		{ $$ = $1; }
	|	init_declarator_list ',' init_declarator { $1->next = $3; $$ = $1; }
	;

init_declarator:
		declarator			{ $$ = $1; }
	|	declarator '=' initializer   { $$ = $1; }
	;

initializer:
	;

declaration_list:
		declaration
	|	declaration_list declaration
				{
					$$ = $1;
					$$->right = $2;
				}
	;

parameter_type_list:
		parameter_declaration { $$ = $1; }
	|	parameter_type_list ',' parameter_declaration { $$->next = $3; }
	;

parameter_declaration:
		type_specifier declarator { mk_type( $1, $2 ); $$ = $2; }
	;

compound_statement:
		'{' '}'					{ $$ = 0; }
	|	'{' statement_list '}'	{ $$ = $2; printf( "statement list\n" ); }
	|	'{' declaration_list '}'	{ $$ = $2; printf( "dec list\n" ); }
	|	'{' declaration_list statement_list '}' { $$ = add_leaf_right( $2, $3 ); }
	;

statement_list:
		statement	{	$$ = $1; }
	|	statement_list statement
					{
						$$ = $1;
						$$->right = $2;
					}

statement:
		postfix_expression ';'	{ $$ = $1; }
	|	assignment_expression ';'
	|	jump_statement	{ printf( "jump statement\n" ); }
	|	';' { $$ = (node *)0; }
	;

jump_statement:
		RETURN ';' {}
	|	RETURN ID ';' {}
	|	RETURN unary_expression ';' {}
	;

function_def:
		type_specifier declarator compound_statement
			{
				printf( "function def with args\n" );
				$$ = mkleaf_function_def( $1, $2, $3 );
				add_tree( $$ );
			}
	;

function_call:
		ID '(' ')'
			{
				node * id = mknode( OP_CALL, $1, 0, 0 );
				$$ = id;
				printf( "function call\n" );
			}
	;

primary_expression:
		CONSTANT_INT {  }
	|	STRING_LITERAL { }
	|	ID		{ }
	;
	
postfix_expression:
		primary_expression	{  }
	|	function_call		{ $$ = $1; }
	|	postfix_expression '[' primary_expression ']'
	|	postfix_expression '.' postfix_expression
	|	postfix_expression INC_OP
	|	postfix_expression DEC_OP
	;

unary_expression:
		postfix_expression
	|	INC_OP unary_expression {}
	|	DEC_OP unary_expression {}
	;

assignment_expression:
		unary_expression assignment_op assignment_expression
	;

assignment_op:
		'='
	;

%%

#include <stdio.h>

extern FILE *yyin;

int main( int argc, char * argv[] )
{
	if( argc > 1 )
	{
		if( !( yyin = fopen( argv[1], "r" ) ) )
		{
			printf( "Error reading source file %s.\n", argv[1] );
			exit(0);
		}
	}
	else
	{
		printf( "No source file specified.\n" );
		exit(0);
	}

	init_sym_tab();

	yyparse();
	fclose( yyin );

	dump_sym_tab();
	printf( "Generating MUDAsm.\n" );
	emit_asm();
}

int yyerror( char * s )
{
	printf( "(error) line %d: %s\n", line, s );
	printf( "Didn't create output asm.\n" );
	exit(0);
}