231 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			231 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #include <xp/stx/stx.h>
 | ||
|  | 
 | ||
|  | #ifdef _DOS
 | ||
|  | 	#include <stdio.h>
 | ||
|  | 	#define xp_printf printf
 | ||
|  | #else
 | ||
|  | 	#include <xp/bas/stdio.h>
 | ||
|  | 	#include <xp/bas/locale.h>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #include <xp/stx/parser.h>
 | ||
|  | #include <xp/stx/bootstrp.h>
 | ||
|  | #include <xp/stx/class.h>
 | ||
|  | #include <xp/stx/bytecode.h>
 | ||
|  | #include <xp/stx/interp.h>
 | ||
|  | 
 | ||
|  | #ifdef __linux
 | ||
|  | #include <mcheck.h>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | struct ss_t | ||
|  | { | ||
|  | 	const xp_char_t* text; | ||
|  | 	xp_size_t index; | ||
|  | }; | ||
|  | 
 | ||
|  | typedef struct ss_t ss_t; | ||
|  | 
 | ||
|  | int ss_func (int cmd, void* owner, void* arg) | ||
|  | { | ||
|  | 
 | ||
|  | 	if (cmd == XP_STX_PARSER_INPUT_OPEN) { | ||
|  | 		ss_t* ss = *(ss_t**)owner; | ||
|  | 		ss->text = (const xp_char_t*)arg; | ||
|  | 		ss->index = 0; | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	else if (cmd == XP_STX_PARSER_INPUT_CLOSE) { | ||
|  | 		/*ss_t* ss = (ss_t*)owner; */ | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	else if (cmd == XP_STX_PARSER_INPUT_CONSUME) { | ||
|  | 		ss_t* ss = (ss_t*)owner; | ||
|  | 		xp_cint_t* c = (xp_cint_t*)arg; | ||
|  | 		if (ss->text[ss->index] == XP_CHAR('\0')) { | ||
|  | 			*c = XP_CHAR_EOF; | ||
|  | 		} | ||
|  | 		else *c = ss->text[ss->index++]; | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	else if (cmd == XP_STX_PARSER_INPUT_REWIND) { | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	return -1; | ||
|  | } | ||
|  | 
 | ||
|  | struct stdio_t | ||
|  | { | ||
|  | 	XP_FILE* stdio; | ||
|  | }; | ||
|  | 
 | ||
|  | typedef struct stdio_t stdio_t; | ||
|  | 
 | ||
|  | int stdio_func (int cmd, void* owner, void* arg) | ||
|  | { | ||
|  | 
 | ||
|  | 	if (cmd == XP_STX_PARSER_INPUT_OPEN) { | ||
|  | 		stdio_t* p = *(stdio_t**)owner; | ||
|  | 		p->stdio = xp_fopen ((const xp_char_t*)arg, XP_TEXT("r")); | ||
|  | 		if (p->stdio == XP_NULL) return -1; | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	else if (cmd == XP_STX_PARSER_INPUT_CLOSE) { | ||
|  | 		stdio_t* p = (stdio_t*)owner; | ||
|  | 		xp_fclose (p->stdio); | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	else if (cmd == XP_STX_PARSER_INPUT_CONSUME) { | ||
|  | 		stdio_t* p = (stdio_t*)owner; | ||
|  | 		xp_cint_t* c = (xp_cint_t*)arg; | ||
|  | 		xp_cint_t t = xp_fgetc (p->stdio);	 | ||
|  | 		if (t == XP_CHAR_EOF) { | ||
|  | 			if (xp_ferror (p->stdio)) return -1; | ||
|  | 			*c = XP_CHAR_EOF; | ||
|  | 		} | ||
|  | 		else *c = t; | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	else if (cmd == XP_STX_PARSER_INPUT_REWIND) { | ||
|  | 		return 0; | ||
|  | 	} | ||
|  | 	return -1; | ||
|  | } | ||
|  | 
 | ||
|  | int xp_main (int argc, xp_char_t* argv[]) | ||
|  | { | ||
|  | 	xp_stx_t stx; | ||
|  | 	xp_stx_parser_t parser; | ||
|  | 
 | ||
|  | #ifdef __linux
 | ||
|  | 	mtrace (); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /*
 | ||
|  | #ifndef _DOS
 | ||
|  | 	if (xp_setlocale () == -1) { | ||
|  | 		printf ("cannot set locale\n"); | ||
|  | 		return -1; | ||
|  | 	} | ||
|  | #endif
 | ||
|  | */ | ||
|  | 
 | ||
|  | 	if (argc != 2) { | ||
|  | 		xp_printf (XP_TEXT("usage: %s class_name\n"), argv[0]); | ||
|  | 		return -1; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (xp_stx_open (&stx, 10000) == XP_NULL) { | ||
|  | 		xp_printf (XP_TEXT("cannot open stx\n")); | ||
|  | 		return -1; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if (xp_stx_bootstrap(&stx) == -1) { | ||
|  | 		xp_stx_close (&stx); | ||
|  | 		xp_printf (XP_TEXT("cannot bootstrap\n")); | ||
|  | 		return -1; | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	if (xp_stx_parser_open(&parser, &stx) == XP_NULL) { | ||
|  | 		xp_printf (XP_TEXT("cannot open parser\n")); | ||
|  | 		return -1; | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	{ | ||
|  | 	/*
 | ||
|  | 		ss_t ss; | ||
|  | 		parser.input_owner = (void*)&ss; | ||
|  | 		parser.input_func = ss_func; | ||
|  | 		xp_stx_parser_parse_method (&parser, 0,  | ||
|  | 			XP_TEXT("isNil\n^true")); | ||
|  | 	*/ | ||
|  | 		stdio_t stdio; | ||
|  | 		xp_word_t n = xp_stx_lookup_class (&stx, argv[1]); | ||
|  | 		xp_word_t m; | ||
|  | 
 | ||
|  | 		parser.input_owner = (void*)&stdio; | ||
|  | 		parser.input_func = stdio_func; | ||
|  | 
 | ||
|  | 		if (n == stx.nil) { | ||
|  | 			xp_printf (XP_TEXT("Cannot find class - %s\n"), argv[1]); | ||
|  | 			goto exit_program; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		/* compile the method to n's class */ | ||
|  | 		if (xp_stx_parser_parse_method (&parser, XP_STX_CLASS(&stx,n),  | ||
|  | 			(void*)XP_TEXT("test.st")) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (xp_stx_parser_parse_method (&parser, stx.class_symbol, | ||
|  | 			(void*)XP_TEXT("test1.st")) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (xp_stx_parser_parse_method (&parser, stx.class_symbol, | ||
|  | 			(void*)XP_TEXT("test2.st")) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (xp_stx_parser_parse_method (&parser, stx.class_string, | ||
|  | 			(void*)XP_TEXT("test3.st")) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		xp_printf (XP_TEXT("\n== Decoded Methods ==\n")); | ||
|  | 		if (xp_stx_decode(&stx, XP_STX_CLASS(&stx,n)) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		xp_printf (XP_TEXT("\n== Decoded Methods for Symbol ==\n")); | ||
|  | 		if (xp_stx_decode(&stx, stx.class_symbol) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		xp_printf (XP_TEXT("\n== Decoded Methods for String ==\n")); | ||
|  | 		if (xp_stx_decode(&stx, stx.class_string) == -1) { | ||
|  | 			xp_printf (XP_TEXT("parser error <%s>\n"),  | ||
|  | 				xp_stx_parser_error_string (&parser)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		xp_printf (XP_TEXT("== Running the main method ==\n")); | ||
|  | 		m = xp_stx_lookup_method ( | ||
|  | 			&stx, XP_STX_CLASS(&stx,n), XP_TEXT("main"), xp_false); | ||
|  | 		if (m == stx.nil) {	 | ||
|  | 			xp_printf (XP_TEXT("cannot lookup method main\n")); | ||
|  | 		} | ||
|  | 		else { | ||
|  | 			xp_stx_interp (&stx, n, m); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | exit_program: | ||
|  | 	xp_stx_parser_close (&parser); | ||
|  | 	xp_stx_close (&stx); | ||
|  | 	xp_printf (XP_TEXT("== End of program ==\n")); | ||
|  | 
 | ||
|  | #ifdef __linux
 | ||
|  | 	muntrace (); | ||
|  | #endif
 | ||
|  | 	 | ||
|  | /*
 | ||
|  | #ifdef __linux
 | ||
|  | 	{ | ||
|  | 		char buf[1000]; | ||
|  | 		snprintf (buf, sizeof(buf), "ls -l /proc/%u/fd", getpid()); | ||
|  | 		system (buf); | ||
|  | 	} | ||
|  | #endif
 | ||
|  | */ | ||
|  | 	return 0; | ||
|  | } | ||
|  | 
 |