home *** CD-ROM | disk | FTP | other *** search
- /* GRAPHIC LISP */
- /* Scritto nel 1991-94 da Zoia Andrea Michele */
- /* Via Pergola #1 Tirano (SO) Tel. 0342-704210 */
- /* file closmain.c */
-
- #include"clos.h"
-
- /* variabili globali */
- struct config_s config;
- jmp_buf critical_jmp;
- jmp_buf break_jmp;
- node nilhandler;
- node truehandler;
- node voidhandler;
- FILE *dribble_file=NULL;
- char buf1[MAX_ID_LENGHT+1];
- char buf2[MAX_ID_LENGHT+1];
- char buf3[MAX_ID_LENGHT+1];
-
- /* variabili locali al modulo closmain.c */
- unsigned Break_level_counter=0;
- char *EvalFileName;
- int ReadCmdLineFiles=TRUE;
- int Gargc;
- char **Gargv;
-
- #define N_LISP_STREA 5
- #define N_LISP_G_FUNCS 15
- #define N_LISP_S_FUNCS 159
- #ifdef __NOGRAPH__
- #define N_LISP_FUNCS N_LISP_S_FUNCS
- #else
- #define N_LISP_FUNCS N_LISP_S_FUNCS + N_LISP_G_FUNCS
- #endif
-
- #define MINSTRINGS 5000
- #define MINNODES 1000L+N_LISP_FUNCS*2L+3L+N_LISP_STREA*2L
- #define MINHASH 100L +N_LISP_FUNCS+2L +N_LISP_STREA
-
- struct env_s{
- n_func address;
- char *name;
- }lf[N_LISP_FUNCS+N_LISP_STREA]={
- lf_backquote ,"BACKQUOTE", lf_defmacro ,"DEFMACRO",
- lf_function ,"FUNCTION", lf_dotimes ,"DOTIMES",
- lf_print ,"PRINT", lf_defun ,"DEFUN",
- lf_defvar ,"DEFVAR", lf_load ,"LOAD",
- lf_gc ,"GC", lf_plus ,"+",
- lf_minus ,"-", lf_mult ,"*",
-
- lf_div ,"/", lf_plusone ,"ADD1",
- lf_minusone ,"SUB1", lf_if ,"IF",
- lf_less ,"<", lf_great ,">",
- lf_atom ,"ATOM", lf_gettime ,"GET-TIME",
- lf_oblist ,"OBLIST", lf_input ,"INPUT",
-
- lf_cons ,"CONS", lf_cdr ,"CDR",
- lf_car ,"CAR", lf_quote ,"QUOTE",
- lf_lambda ,"LAMBDA", lf_setf ,"SETF",
- lf_sin ,"SIN", lf_cos ,"COS",
- lf_tan ,"TAN", lf_asin ,"ASIN",
-
- lf_acos ,"ACOS", lf_atan ,"ATAN",
- lf_sinh ,"SINH", lf_cosh ,"COSH",
- lf_tanh ,"TANH", lf_exp ,"EXP",
- lf_log ,"LOG", lf_log10 ,"LOG10",
- lf_sqrt ,"SQRT", lf_break ,"BREAK",
-
- lf_getlenv ,"GET-LENV", lf_getgenv ,"GET-GENV",
- lf_let ,"LET", lf_letspecial ,"LET*",
- lf_list ,"LIST", lf_do ,"DO",
- lf_plist ,"PLIST", lf_str2name ,"STR2NAME",
- lf_name2str ,"NAME2STR", lf_eval ,"EVAL",
-
- lf_exit ,"EXIT", lf_not ,"NULL"/**/,
- lf_iszero ,"=0"/**/, lf_and ,"AND",
- lf_or ,"OR", lf_eq ,"EQ",
- lf_apply ,"APPLY", lf_funcall ,"FUNCALL",
- lf_strcat ,"STRCAT", lf_iszero ,"ZEROP",
-
- lf_loop ,"LOOP", lf_return ,"RETURN",
- lf_car ,"FIRST"/**/, lf_cdr ,"REST",/**/
- lf_set ,"SET", lf_setf ,"SETQ",/**/
- lf_continue ,"CONTINUE", lf_consp ,"CONSP",
- lf_listp ,"LISTP", lf_numberp ,"NUMBERP",
-
- lf_symbolp ,"SYMBOLP", lf_endp ,"ENDP",
- lf_not ,"NOT", lf_mapcar ,"MAPCAR",
- lf_prog1 ,"PROG1", lf_progn ,"PROGN",
- lf_when ,"WHEN", lf_unless ,"UNLESS",
- lf_defclass ,"DEFCLASS", lf_plusp ,"PLUSP",
-
- lf_minusp ,"MINUSP", lf_evenp ,"EVENP",
- lf_oddp ,"ODDP", lf_cond ,"COND",
- lf_numequal ,"=", lf_reverse ,"REVERSE",
- lf_hashstat ,"HASHSTAT", lf_lenght ,"LENGHT",
- lf_dolist ,"DOLIST",
-
- lf_defmethod ,"DEFMETHOD", lf_mkinstance ,"MAKE-INSTANCE",
- lf_functionp ,"FUNCTIONP", lf_elt ,"ELT",
- lf_dospecial ,"DO*", lf_plusone ,"1+",/**/
- lf_minusone ,"1-",/**/ lf_append ,"APPEND",
- lf_max ,"MAX", lf_min ,"MIN",
-
- lf_abs ,"ABS", lf_rem ,"REM",
- lf_float ,"FLOAT", lf_round ,"ROUND",
- lf_push ,"PUSH", lf_pop ,"POP",
- lf_last ,"LAST", lf_equal ,"EQUAL",
- lf_stringp ,"STRINGP", lf_classp ,"CLASSP",
-
- lf_intp ,"INTP", lf_realp ,"REALP",
- lf_ratiop ,"RATIOP", lf_cnamep ,"CNAMEP",
- lf_enamep ,"ENAMEP", lf_readline ,"READ-LINE",
- lf_stringeq ,"STRING=", lf_stringequal ,"STRING-EQUAL",
-
- lf_assoc ,"ASSOC",
- lf_stacktrace ,"STACKTRACE", lf_sysfuncp ,"SYSFUNCP",
- lf_ufuncp ,"UFUNCP", lf_methodp ,"METHODP",
- lf_accessorp ,"ACCESSORP", lf_valuep ,"VALUEP",
-
- lf_readchar ,"READCHAR", lf_strprintf ,"STRPRINTF",
- lf_fopen ,"FOPEN", lf_fclose ,"FCLOSE",
- lf_fprint ,"FPRINT", lf_fseek ,"FSEEK",
- lf_freadbyte ,"FREADBYTE", lf_fwritebyte ,"FWRITEBYTE",
- lf_ftell ,"FTELL", lf_finput ,"FINPUT",
-
- lf_feof ,"FEOF", lf_ferror ,"FERROR",
- lf_fclearerr ,"FCLEARERR",
-
- lf_curpos ,"CURPOS", lf_streamp ,"STREAMP",
- lf_fscanf ,"FSCANF", lf_trace ,"TRACE",
- lf_untrace ,"UNTRACE", lf_textcolor ,"TEXTCOLOR",
- lf_str2real ,"STR2REAL", lf_str2int ,"STR2INT",
- lf_cls ,"CLS", lf_strsub ,"STRSUB",
-
- lf_str2ascii ,"STR2ASCII", lf_strnum ,"STRNUM",
- lf_strlen ,"STRLEN", lf_while ,"WHILE",
- lf_nconc ,"NCONC", lf_dribble ,"DRIBBLE",
- lf_prog ,"PROG", lf_go ,"GO",
- lf_macrop ,"MACROP", lf_fixlist ,"FIXLIST",
-
- #ifndef __NOGRAPH__
- lf_graphopen ,"GMODE", lf_graphclear ,"GCLEAR",
- lf_gpencolor ,"GPENCOLOR", lf_gpentick ,"GPENTICK",
- lf_gpentype ,"GPENTYPE", lf_gbrushcolor ,"GBRUSHCOLOR",
- lf_gbrushtype ,"GBRUSHTYPE", lf_gputpixel ,"GPUTPIXEL",
- lf_gmoveto ,"GMOVETO", lf_glineto ,"GLINETO",
- lf_gfillpoly ,"GFILLPOLY", lf_gfillellipse ,"GFILLELLIPSE",
- lf_gfillsector ,"GFILLSECTOR", lf_ggetpixel ,"GGETPIXEL",
- lf_gouttext ,"GOUTTEXT",
- #endif
-
-
- (n_func)stdin ,"*STDIN*", (n_func)stdout ,"*STDOUT*",
- (n_func)stderr ,"*STDERR*", (n_func)stdprn ,"*STDPRN*",
- (n_func)stdaux ,"*STDAUX*"
- };
-
-
- void make_environment();
- int lisp_malloc();
- int parse_cmdline();
- void read_cmdline_files();
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- extern int loop_jmp_valid; /* clos_lf6 */
- extern int go_jmp_valid; /* clos_lf6 */
- /******************************************************************/
- /* Solo per TurboC */
- /* si allocano 0x100 bytes in modo che quando si verifica */
- /* uno stack-overflow non si corrompa la memoria dei nodi */
- /* NB: la variabile _stklen e' uguale a 0xff00 */
-
- #ifdef __TURBOC__
- #ifndef _Windows
- malloc(0x100);
- #endif
- #endif
- /* */
- /******************************************************************/
-
- Gargc=argc;
- Gargv=argv;
- if(parse_cmdline(argc,argv))
- return ERROR;
- if(lisp_malloc((lsiz_t)config.nodes,(lsiz_t)config.hashes,(lsiz_t)config.strings))
- return ERROR;
- make_environment();
- if(clos_non_ansi_init())
- return ERROR;
-
- switch(setjmp(critical_jmp)){
- case LONGJMP_SET:
- /* la prima volta che si chiama NLSETJMP */
- break;
- case LONGJMP_STACK:
- /* stack-overflow */
- error(E_STACK,ERR_TNORM|ERR_MERRORMSGBOX|ERR_PVOID,NULL);
- node_criticalgc();
- break;
- case LONGJMP_CONTROLC:
- /* control-c */
- node_criticalgc();
- error(E_CTRLC,ERR_TNORM|ERR_MERROR|ERR_PVOID,NULL);
- break;
- case LONGJMP_CRITICAL:
- node_criticalgc();
- /* out-of-memory ecc.. */
- break;
- }
- #ifdef _Windows
- /////////////////////////////////////
- ClosDDEUnInit();
- ClosDDEInit();
- ////////////////////////////////////
- #endif
-
-
-
- /* main loop */
- /* local-environment e' una lista di a-list */
- /* il global-environment e' una a-list */
- /* NOTA BENE: NIL e T sono due nodi che non si possono mai unbound-are */
-
- loop_jmp_valid=FALSE;
- go_jmp_valid =FALSE;
- Break_level_counter=0;
- Break_level_counter--;
- /* distruggi la lock-list */
- lisp_main_loop(NIL,NIL,node_lockreset());
- return OK;
- }
-
-
- void lisp_main_loop(global_environment,local_environment,lastlock)
- node global_environment;
- node local_environment;
- node lastlock;
- {
- extern int loop_jmp_valid; /* clos_lf6 */
- int old_loop_jmp_valid;
- extern int go_jmp_valid; /* clos_lf6 */
- int old_go_jmp_valid;
- node_p nout;
- jmp_buf this_break_jmp;
- char prompt[10];
- unsigned this_break_level=(++Break_level_counter);
- static node in;
-
-
- switch(setjmp(break_jmp)){
- case LONGJMP_SET:
- memcpy(this_break_jmp,break_jmp,sizeof(jmp_buf));
- old_loop_jmp_valid=loop_jmp_valid;
- old_go_jmp_valid=go_jmp_valid;
- break;
- case LONGJMP_CONTINUE:
- if(!this_break_level){
- error(E_BADCONTINUE,ERR_MERROR|ERR_TNORM|ERR_PVOID,NULL);
- break;
- }
- Break_level_counter--;
- return;
- case LONGJMP_ERROR: /* errori sintattici,unbounds,ecc.... */
- go_jmp_valid=old_go_jmp_valid;
- loop_jmp_valid=old_loop_jmp_valid;
- break;
- }
- if(ReadCmdLineFiles){
- ReadCmdLineFiles=FALSE;
- read_cmdline_files();
- }
- for(;;){ /* LISP MAIN LOOP */
- memcpy(break_jmp,this_break_jmp,sizeof(jmp_buf));
- Break_level_counter=this_break_level;
- if(!this_break_level){
- sprintf(prompt,"%s",STANDARD_PROMPT);
- }else{
- sprintf(prompt,"(%u)%s",this_break_level,STANDARD_PROMPT);
- }
- node_signal(lastlock);
- in=input_func(stdin,stdout,prompt);
- if(in==VOID)continue;
- eval(in,&nout,global_environment,local_environment,EVAL_NORM);
- fprint_func(calc_pointer(&nout),stdout);
- lisp_print_string("\n",stdout);
- }
- }
-
-
-
- void make_environment()
- {
- node ni;
- node no;
- int i,j;
-
-
- /* NB: sono stati allocati almeno N_LISP_FUNCS*2+2 nodi */
- /* almeno N_LISP_FUNCS+2 Hash entryes */
- /* ed almeno 1000 caratteri per le stringhe */
- /* 1000 non e' un vlore esatto ma dovrebbe essere sufficiente */
- /* a contenere almeno tutti i nomi delle funzioni */
-
- TYPE(NIL=node_alloc(NIL_IDENTIFIER))|=NT_IS_NAME|NT_HAS_NAME|NT_HAS_VALUE;
- VALUE(NIL)=NIL;
-
- TYPE(T=node_alloc(TRUE_IDENTIFIER))|=NT_IS_NAME|NT_HAS_NAME|NT_HAS_VALUE|NT_HAS_CLASS;
- VALUE(T)=T;
- CLASS(T)=NIL;
-
- for(i=0;i<N_LISP_FUNCS;i++){
- TYPE(no=node_alloc(lf[i].name))|=NT_IS_NAME|NT_HAS_NAME|NT_HAS_FUNCTION;
- TYPE(ni=node_make())|=NT_IS_VALUE|NT_SYSFUNC;
- SYSFUNC(ni)=lf[i].address;
- FUNCTION(no)=ni;
- }
- for(j=0;j<N_LISP_STREA;i++,j++){
- TYPE(no=node_alloc(lf[i].name))|=NT_IS_NAME|NT_HAS_NAME|NT_HAS_VALUE;
- TYPE(ni=node_make())|=NT_IS_VALUE|NT_STREAM;
- STREAM(ni)=(FILE*)lf[i].address;
- VALUE(no)=ni;
- }
-
- TYPE(no=node_alloc(WINDOWS_ID))|=NT_IS_NAME|NT_HAS_NAME|NT_HAS_VALUE;
- #ifdef _Windows
- VALUE(no)=T;
- #else
- VALUE(no)=NIL;
- #endif
- }
-
-
- void read_cmdline_files()
- {
- int i;
-
- for(i=1;i<Gargc;i++){
- if(!(Gargv[i][0]=='/' || Gargv[i][0]=='-')){
- sprintf(buf1,"reading file %s\n",Gargv[i]);
- lisp_print_string(buf1,stdout);
- eval_lisp_file(Gargv[i],NIL,NIL);
- }
- }
- }
-
-
-
-
-
- int parse_cmdline(argc,argv)
- int argc;
- char **argv;
- {
- FILE *cf;
- int i;
- char cnfmark[50];
- char cnfchk[50];
- int write_cfg=FALSE;
- unsigned long lv;
- unsigned uv;
-
-
- strcpy(cnfmark,CONFIGFILE);
- strcat(cnfmark,CLOS_VERSION);
-
- if((cf=fopen(CONFIGFILE,"r"))==NULL){
- config.nodes=MINNODES;
- config.strings=MINSTRINGS;
- config.hashes=MINHASH;
- config.bad_char_error=FALSE;
- config.case_sensitive=FALSE;
- config.max_id_lenght=50; /* <=MAX_ID_LENGHT */
- config.max_string_lenght=80; /* <=MAX_STR_LENGHT */
- config.gcbeep=TRUE;
- }
- else{
- fread((void*)cnfchk,strlen(cnfmark)+1,1,cf);
- if(strcmp(cnfmark,cnfchk)){
- return error(E_INVALIDCFGFILE,ERR_TNORM|ERR_MERRORMSGBOX|ERR_PSTRING,CONFIGFILE);
- }else{
- fread((void*)&config,sizeof(struct config_s),1,cf);
- fclose(cf);
- }
- }
- for(i=1;i<argc;i++){
- if(argv[i][0]=='/' || argv[i][0]=='-')
- switch(argv[i][1]){
- case 'n':case 'N':sscanf(&argv[i][2],"%lu",&lv);
- if(lv>MINNODES)config.nodes=lv;
- break;
- case 's':case 'S':sscanf(&argv[i][2],"%lu",&lv);
- if(lv>MINSTRINGS)config.strings=lv;
- break;
- case 'h':case 'H':sscanf(&argv[i][2],"%lu",&lv);
- if(lv>MINHASH)config.hashes=lv;
- break;
- case 'i':case 'I':
- sscanf(&argv[i][2],"%u",&uv);
- if(uv<=MAX_ID_LENGHT && uv>=2)config.max_id_lenght=uv;
- break;
- case 'r':case 'R':
- sscanf(&argv[i][2],"%u",&uv);
- if(uv<=MAX_STR_LENGHT && uv>=2)uv=config.max_string_lenght;
- break;
- case 'c':case 'C':config.bad_char_error=argv[i][2]!='-';break;
- case 'a':case 'A':config.case_sensitive=argv[i][2]!='-';break;
- case 'w':case 'W':write_cfg=TRUE;break;
- default:
- return error(E_CMDLINE,ERR_TNORM|ERR_MERRORMSGBOX|ERR_PVOID,NULL);
- }
- }
- if(write_cfg){
- if((cf=fopen(CONFIGFILE,"w"))==NULL){
- error(E_CNFFILE,ERR_TNORM|ERR_MWARN|ERR_PSTRING,CONFIGFILE);
- }
- else{
- fwrite((void*)cnfmark,strlen(cnfmark)+1,1,cf);
- fwrite((void*)&config,sizeof(struct config_s),1,cf);
- fclose(cf);
- }
- }
- return OK;
- }
-
-
- int lisp_malloc(no,ha,st)
- lsiz_t no;
- lsiz_t ha;
- lsiz_t st;
- {
- if(node_malloc(no))
- return error(E_NODEINIT,ERR_MERRORMSGBOX|ERR_TNORM|ERR_PVOID,NULL);
- if(hash_malloc(ha)){
- node_free();
- return error(E_HASHINIT,ERR_MERRORMSGBOX|ERR_TNORM|ERR_PVOID,NULL);
- }
- if(string_malloc(st)){
- hash_free();
- node_free();
- return error(E_STRINGINIT,ERR_MERRORMSGBOX|ERR_TNORM|ERR_PVOID,NULL);
- }
- return OK;
- }
-
-
- void lisp_free()
- {
- string_free();
- hash_free();
- node_free();
- }
-
-
-
-
-
- node eval_lisp_file(name, genv,lenv)
- char *name;
- node genv;
- node lenv;
- {
- node in,n=node_getlastlock();
- node_p nout;
- FILE *LoadFile;
- FILE *PrintFile=NULL;
- jmp_buf this_break_jmp;
-
- memcpy(this_break_jmp,break_jmp,sizeof(jmp_buf));
- switch(setjmp(break_jmp)){
- case LONGJMP_SET:
- break;
- case LONGJMP_CONTINUE:
- error(E_BADCONTINUE,ERR_MERROR|ERR_TNORM|ERR_PVOID,NULL);
- goto ELF_Error;
- case LONGJMP_ERROR: /* errori sintattici,unbounds,ecc.... */
- goto ELF_Error;
- }
-
- if((LoadFile=fopen(name,"r"))==NULL){
- error(E_BADFILE,ERR_MERROR|ERR_PSTRING|ERR_TNORM,name);
- goto ELF_Error;
- }
- nout.node=NIL;
- nout.type=P_ALLNODE;
- while(skip_spaces_tabs_nwl(LoadFile)){
- in=input_func(LoadFile,PrintFile,"");
- /* Uso PrintFile=NULL perche' mettendo direttamente NULL
- il compilatore borlandc si incasina e mette sullo stack
- solo la word 0000 e non la dword 0000:0000
- */
-
- if(in==VOID){
- goto ELF_Error;
- }
- eval(in,&nout,genv,lenv,EVAL_NORM);
- node_signal(n);/* recupera tutto */
- }
- memcpy(break_jmp,this_break_jmp,sizeof(jmp_buf));
- node_signal(n);
- fclose(LoadFile);
- return calc_pointer(&nout);
-
- ELF_Error:;
- memcpy(break_jmp,this_break_jmp,sizeof(jmp_buf));
- node_signal(n);
- fclose(LoadFile);
- return VOID;
- }
-
-
- int skip_spaces_tabs_nwl(f)
- FILE *f;
- {
- int ch;
-
- for(;;){
- switch(getc(f)){
- case EOF:return 0;
- case ' ':case '\t':case '\n':continue;
- case ';': /* skip comment */
- do{
- if((ch=getc(f))==EOF)
- return 0;
- }while(ch!='\n');
- continue;
- default:fseek(f,-1L,SEEK_CUR);return 1;
- }
- }
- }
-