home *** CD-ROM | disk | FTP | other *** search
- /*{{{}}}*/
- /*{{{ #includes*/
- #ifdef VARARGS
- # include <varargs.h>
- #else
- # include <stdarg.h>
- #endif
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- #define CODEHELP_C
-
- #include "keybind.h"
- #include <lib/ori_add_lib.h>
- /*}}} */
-
- /*{{{ variables*/
- public boolean new_vars_enabled=False;
- private int dv_list[int_dummy_vars];
- private boolean dv_init=False;
- /*}}} */
-
- /*{{{ mstrcpy*/
- public unsigned char *mstrcpy(unsigned char const * const s)
- {
- unsigned char *x;
-
- x=kbd_malloc(ustrlen(s)+1);
- ustrcpy(x,s);
-
- return(x);
- }
- /*}}} */
- /*{{{ m_error_po*/
- public void m_error_po(char const * const m)
- {
- error_po();
- fputs(m,stderr);
- }
- /*}}} */
- /*{{{ m_exit*/
- #ifdef VARARGS
- public void m_exit(format,va_alist)char const * const format;va_dcl
- #else
- public void m_exit(char const * const format,...)
- #endif
- { va_list ap;
-
- error_po();
- /*{{{ start arglist handling*/
- # ifdef VARARGS
- va_start(ap);
- # else
- va_start(ap,format);
- # endif
- /*}}} */
- vfprintf(stderr,(char*)format,ap);
- /*{{{ end arglist handling*/
- va_end(ap);
- /*}}} */
- kbd_exit(1);
- }
- /*}}} */
- /*{{{ begin_parse*/
- public void begin_parse(void)
- {
- if (get_single_token()!=BEGIN)
- m_exit(M_WANTBEGIN);
- }
- /*}}} */
- /*{{{ end_parse*/
- public void end_parse(char const * const er)
- {
- if (get_single_token()!=END)
- m_exit(er);
- }
- /*}}} */
- /*{{{ name_parse*/
- public void name_parse
- ( unsigned char *str,
- char const * const er,
- boolean const op
- )
- {
- switch (get_full_token())
- { case OPCODE:
- case OPERATION:
- case VARIABLE:
- if (op)
- {
- case NAME:
- ustrcpy(str,tk_string);
- return;
- }
- default:
- m_exit(er);
- }
- }
- /*}}} */
- /*{{{ name_to_var transform token NAME to token VARIABLE, if possible*/
- public tokens name_to_var(tokens token, int size, boolean newvars)
- { if (token==NAME && newvars)
- { creat_var(tk_string,size,-1);
- for (tk_var=var_list;tk_var;tk_var=tk_var->next)
- if (!ustrcmp(tk_var->var_name,tk_string))
- break;
- token=VARIABLE;
- }
- if (token==VARIABLE && size && size!=tk_var->size)
- m_exit(M_NOVAR);
- return(token);
- }
- /*}}} */
- /*{{{ put variable-adress*/
- public TOKEN *put_var(TOKEN *buff)
- {
-
- switch (name_to_var(get_full_token(),1,new_vars_enabled))
- { case VARIABLE:
- *buff++ = (TOKEN) tk_var->no;
- if (tk_var->size==1)
- break;
- default:
- m_exit(M_NOVAR);
- }
- return(buff);
- }
- /*}}} */
- /*{{{ dummy_var*/
- public int dummy_var(int no)
- {
- /*{{{ maybe init it*/
- if (!dv_init)
- { int i;
- for (i=0;i<int_dummy_vars;dv_list[i++]= -1);
- dv_init=True;
- }
- /*}}} */
- /*{{{ no dummy-vars available -> error*/
- if (no>=int_dummy_vars)
- m_exit(M_NOVAS);
- /*}}} */
- if (dv_list[no]==-1)
- { unsigned char s[10];
-
- sprintf((char*)s,"(dummy%d)",no);
- return(dv_list[no]=creat_var(s,1,-1));
- }
- else
- return(dv_list[no]);
- }
- /*}}} */
- /*{{{ macro-argument variable handling*/
- private int ocl_arg_vars[ocl_max_args];
- private int ocl_loc_vars[ocl_max_args];
- private int ocl_args_used=0;
-
- /*{{{ def_ocl_args*/
- public void def_ocl_args(int no)
- { while (ocl_args_used<no)
- { unsigned char vn[26];
-
- sprintf((char*)vn,"(arg%d)",ocl_args_used);
- ocl_arg_vars[ocl_args_used]=creat_var(vn,1,-1);
- sprintf((char*)vn,"(loc%d)",ocl_args_used);
- ocl_loc_vars[ocl_args_used]=creat_var(vn,1,-1);
- ocl_args_used++;
- }
- }
- /*}}} */
- /*{{{ ocl_arg_var*/
- public int ocl_arg_var(int no)
- {
- if (no>=ocl_args_used)
- m_exit(M_CRASH);
- return(ocl_arg_vars[no]);
- }
- /*}}} */
- /*{{{ ocl_loc_var*/
- public int ocl_loc_var(int no)
- {
- if (no>=ocl_args_used)
- m_exit(M_CRASH);
- return(ocl_loc_vars[no]);
- }
- /*}}} */
- /*}}} */
- /*{{{ isdummy*/
- public boolean isdummy(int x)
- { int i;
-
- if (dv_init) for (i=0;i<int_dummy_vars;i++) if (dv_list[i]==x) return(True);
- return(False);
- }
- /*}}} */
- /*{{{ create a jump-command*/
- public TOKEN *generate_jmp(TOKEN j, TOKEN *ad, TOKEN *dest)
- {
- switch (j)
- { case M_JMP:
- case M_CALL:
- case M_JMP_TRUE:
- case M_JMP_FALSE:
- break;
- default:
- m_exit(M_NOJUMP);
- }
- *ad++ = j;
- *ad= dest-(ad+1);
-
- return(ad+1);
- }
- /*}}} */
- /*{{{ parse_term*/
- /*{{{ destination save register handling*/
- typedef struct { int old;int save;boolean changed;boolean chg_use;TOKEN *save_start; } DEST_DAT;
-
- /*{{{ start_dest_handle*/
- private void start_dest_handle(DEST_DAT *t,int dest,TOKEN **buff,int *dummy_base)
- {
- t->save_start= *buff;
- t->old=dest;
- t->save=dummy_var((*dummy_base)++);
- t->changed=t->chg_use=!opt_mac;
- *(*buff)++=M_PUSH_INT;
- *(*buff)++=(TOKEN)dest;
- *(*buff)++=M_POP_INT;
- *(*buff)++=(TOKEN)t->save;
- }
- /*}}} */
- /*{{{ end_dest_handle*/
- private void end_dest_handle(DEST_DAT *t)
- { if (!t->chg_use)
- /*{{{ saved target variable not used, so clear these statements*/
- { *(t->save_start)++=O_NOP;
- *(t->save_start)++=O_NOP;
- *(t->save_start)++=O_NOP;
- *(t->save_start)++=O_NOP;
- }
- /*}}} */
- }
- /*}}} */
- /*{{{ set_dest*/
- private void set_dest(TOKEN *buff,int x,DEST_DAT *t)
- { *buff=x;
- if (x==t->old) t->changed=True;
- }
- /*}}} */
- /*{{{ set_source*/
- private void set_source(TOKEN *buff,int x,DEST_DAT *t)
- { if (x==t->old && t->changed)
- { *buff=t->save;
- t->chg_use=True;
- }
- else
- *buff=x;
- }
- /*}}} */
- /*}}} */
-
- /*{{{ recursion for term-parsing*/
- public TOKEN *rpt(tokens token,TOKEN *buff,int dest,int dummy,boolean *ret_used,DEST_DAT *t)
- { tokens op=name_to_var(token,0,new_vars_enabled);
-
- check_length(buff);
- switch (op)
- { case VARIABLE:
- /*{{{ maybe PUSH new POP old*/
- { int x=tk_var->no;
-
- if (tk_var->size==1)
- /*{{{ handle int var*/
- { if (x!=dest)
- { *buff++=M_PUSH_INT;
- set_source(buff++,x,t);
- *buff++=M_POP_INT;
- set_dest(buff++,dest,t);
- }
- }
- /*}}} */
- else
- /*{{{ handle int array*/
- { begin_parse();
- op=get_full_token();
- switch(op)
- { case NUMBER:
- *buff++=M_PUSH_INT;
- set_source(buff++,x+tk_val,t);
- *buff++=M_POP_INT;
- set_dest(buff++,dest,t);
- break;
- case VARIABLE:
- if (tk_var->size==1)
- { *buff++=M_PUSH_INT_X;
- *buff++=(TOKEN)x;
- *buff++=(TOKEN)tk_var->no;
- *buff++=M_POP_INT;
- set_dest(buff++,dest,t);
- break;
- }
- default:
- if (!(buff=rpt(op,buff,dummy_var(dummy),dummy+1,ret_used,t))) return(0);
- *buff++=M_PUSH_INT_X;
- *buff++=(TOKEN)x;
- *buff++=(TOKEN)dummy_var(dummy);
- *buff++=M_POP_INT;
- set_dest(buff++,dest,t);
- break;
- }
- end_parse(M_WANTEND);
- }
- /*}}} */
- break;
- }
- /*}}} */
- case EVAL:
- /*{{{ get value from called macro*/
- { TOKEN *call;
- TOKEN *jmp;
-
- /*{{{ push dummy vars*/
- { int i;
-
- for (i=0;i<dummy;i++)
- { *buff++=M_PUSH_INT;
- *buff++=(TOKEN)dummy_var(i);
- }
- }
- /*}}} */
- /*{{{ call the macro*/
- buff=generate_jmp(M_CALL,call=buff,buff);
- buff=generate_jmp(M_JMP,jmp=buff,buff);
- generate_jmp(M_CALL,call,buff);
- if (!(buff=parse_macro(buff,0,ret_used))) return(0);
- *buff++=M_END_MACRO;
- generate_jmp(M_JMP,jmp,buff);
- /*}}} */
- /*{{{ pop dummy vars*/
- { int i;
-
- for (i=dummy-1;i>=0;i--)
- { *buff++=M_POP_INT;
- *buff++=(TOKEN)dummy_var(i);
- }
- }
- /*}}} */
- /*{{{ get return value*/
- *buff++=M_PUSH_INT;
- *buff++=(TOKEN)return_var;
- *buff++=M_POP_INT;
- set_dest(buff++,dest,t);
- /*}}} */
- break;
- }
- /*}}} */
- case PRE:
- /*{{{ do the action first*/
- {
- /*{{{ push dummy vars*/
- { int i;
-
- for (i=0;i<dummy;i++)
- { *buff++=M_PUSH_INT;
- *buff++=(TOKEN)dummy_var(i);
- }
- }
- /*}}} */
- if (!(buff=parse_macro(buff,0,ret_used))) return(0);
- /*{{{ pop dummy vars*/
- { int i;
-
- for (i=dummy-1;i>=0;i--)
- { *buff++=M_POP_INT;
- *buff++=(TOKEN)dummy_var(i);
- }
- }
- /*}}} */
- if (!(buff=rpt(get_full_token(),buff,dest,dummy,ret_used,t))) return(0);
- break;
- }
- /*}}} */
- case COUNTER:
- /*{{{ convert boolean to int*/
- { TOKEN *x;
-
- /*{{{ set-counter dest 0*/
- *buff++ = M_SET_COUNTER;
- set_dest(buff++,dest,t);
- *buff++ = 0;
- /*}}} */
- if (!(buff=parse_cond(buff,dummy,ret_used))) return(0);
- buff=generate_jmp(M_JMP_FALSE,x=buff,buff);
- /*{{{ set-counter dest 1*/
- *buff++ = M_SET_COUNTER;
- *buff++ = (TOKEN) dest;
- *buff++ = 1;
- /*}}} */
- generate_jmp(M_JMP_FALSE,x,buff);
- break;
- }
- /*}}} */
- case OPERATION:
- /*{{{ operation*/
- *buff++ = M_SET_COUNTER;
- set_dest(buff++,dest,t);
- if (tk_operation->place<0)
- { if (tk_operation->length>1) goto error_code;
- *buff++ = tk_operation->ops[0];
- }
- else
- *buff++ = O_CALL_FIX+tk_operation->place+1;
- break;
- /*}}} */
- case OPCODE:
- /*{{{ opcode*/
- { *buff++ = M_SET_COUNTER;
- set_dest(buff++,dest,t);
- *buff++ = tk_key->num;
- break;
- }
- /*}}} */
- case DECODE_BUFFER:
- /*{{{ decode a position to a buffer-position*/
- { int v1;
- int v2;
- tokens tok;
-
- if ((tok=name_to_var(get_full_token(),1,new_vars_enabled))==VARIABLE)
- v1=tk_var->no;
- else if (!(buff=rpt(tok,buff,v1=dummy_var(dummy),dummy+1,ret_used,t)))
- return(0);
- if ((tok=name_to_var(get_full_token(),1,new_vars_enabled))==VARIABLE)
- v2=tk_var->no;
- else if (!(buff=rpt(tok,buff,v2=dummy_var(dummy+1),dummy+2,ret_used,t)))
- return(0);
- *buff++=M_GET_BUFFER;
- *buff++=(TOKEN)v1;
- *buff++=(TOKEN)v2;
- *buff++=M_POP_INT;
- *buff++=(TOKEN)dest;
- break;
- }
- /*}}} */
- case FOLD_SL:
- case FOLD_EL:
- /*{{{ get length of fold-comment-string*/
- *buff++=M_FOLD_DATA;
- *buff++=(op==FOLD_SL)?0:2;
- set_dest(buff++,dest,t);
- break;
- /*}}} */
- case FOLD_M1:
- case FOLD_M2:
- case FOLD_M3:
- case FOLD_M4:
- case FOLD_S:
- case FOLD_E:
- /*{{{ get data from fold comment*/
- if (!(buff=rpt(get_full_token(),buff,dummy_var(dummy),dummy+1,ret_used,t))) return(0);
- *buff++=M_FOLD_DATA;
- *buff++=(op==FOLD_M1)? 4:
- (op==FOLD_M2)? 5:
- (op==FOLD_M3)? 6:
- (op==FOLD_M4)? 7:
- (op==FOLD_S) ? 1:
- 3;
- *buff++=(TOKEN)dummy_var(dummy);
- *buff++=M_POP_INT;
- set_dest(buff++,dest,t);
- break;
- /*}}} */
- case FILETYPE:
- case STORE_CHAR:
- case READ_REPEAT:
- case SET_ENTER:
- case SET_S_ENTER:
- case STORE_MARK:
- case STORE_X:
- case STORE_Y:
- /*{{{ get data from origami*/
- *buff++ = (token==FILETYPE) ? M_FILETYP :
- (token==SET_ENTER) ? M_ENTERED :
- (token==STORE_MARK) ? M_STORE_MARK :
- (token==STORE_X) ? M_POS_TO_COUNTER :
- (token==STORE_Y) ? M_STORE_LINE_NO :
- (token==STORE_CHAR) ? M_STORE_C :
- (token==READ_REPEAT) ? M_READ_REPEAT :
- M_S_ENTERED;
- set_dest(buff++,dest,t);
- break;
- /*}}} */
- case NUMBER:
- /*{{{ M_SET_COUNTER dest value*/
- { *buff++=M_SET_COUNTER;
- set_dest(buff++,dest,t);
- *buff++=(TOKEN)tk_val;
- break;
- }
- /*}}} */
- case ADD:
- case MINUS:
- case MULT:
- case DIV:
- case MOD:
- /*{{{ list of arguments*/
- { token=get_full_token();
- if (token!=BEGIN)
- /*{{{ compiling the unary -*/
- { if (op!=MINUS)
- m_exit(M_WANTBEGIN);
- if (!(buff=rpt(token,buff,dest,dummy,ret_used,t)))
- return(0);
- *buff++=M_INV_COUNTER;
- set_dest(buff++,dest,t);
- break;
- }
- /*}}} */
- if (!(buff=rpt(get_full_token(),buff,dest,dummy,ret_used,t))) return(0);
- token=name_to_var(get_full_token(),0,new_vars_enabled);
- do
- /*{{{ code one argument from list*/
- { check_length(buff);
- switch (token)
- { case COMMA: break;
- case VARIABLE:
- if (tk_var->size==1)
- /*{{{ code: op var var*/
- { int x=tk_var->no;
-
- /*{{{ code the operation*/
- switch (op)
- { /* MINUS uses the code for ADD too!! */
- case MINUS: *buff++=M_INV_COUNTER;*buff++=(TOKEN)dest;
- case ADD: *buff++=M_SUM_COUNTER;break;
- case MULT: *buff++=M_MULT;break;
- case DIV: *buff++=M_DIV;break;
- case MOD: *buff++=M_MOD;break;
- default: m_exit(M_CRASH);
- }
- /*}}} */
- /*{{{ code arguments*/
- set_dest(buff++,dest,t);
- set_source(buff++,x,t);
- /*}}} */
- if (op==MINUS) { *buff++=M_INV_COUNTER;*buff++=(TOKEN)dest; }
- break;
- }
- /*}}} */
- default:
- if (!(buff=rpt(token,buff,dummy_var(dummy),dummy+1,ret_used,t)))
- return(0);
- /*{{{ code the operation*/
- switch (op)
- { /* MINUS uses the code for ADD too!! */
- case MINUS:
- *buff++=M_INV_COUNTER;*buff++=(TOKEN)dummy_var(dummy);
- case ADD:
- *buff++=M_SUM_COUNTER;break;
- case MULT:
- *buff++=M_MULT;break;
- case DIV:
- *buff++=M_DIV;break;
- case MOD:
- *buff++=M_MOD;break;
- default:
- m_exit(M_CRASH);
- }
- /*}}} */
- *buff++=dest;
- *buff++=dummy_var(dummy);
- }
- }
- /*}}} */
- while ((token=name_to_var(get_full_token(),1,new_vars_enabled))!=END);
- break;
- }
- /*}}} */
- case MACRO:
- /*{{{ code a one Token macro as it's value'*/
- if (ustrlen(tk_string)==1)
- /*{{{ code the integer value of a given character*/
- { *buff++=M_SET_COUNTER;
- *buff++=(TOKEN)dest;
- *buff++=(TOKEN)tk_string[0];
- break;
- }
- /*}}} */
- else
- goto error_code;
- /*}}} */
- case NAME:
- /*{{{ code C-x statements*/
- if (tk_string[0]=='C' && tk_string[1]=='-' && tk_string[3]=='\0')
- { *buff++=M_SET_COUNTER;
- *buff++=(TOKEN)dest;
- *buff++=ctrl_c[tk_string[2]];
- break;
- }
- else
- goto error_code;
- /*}}} */
- default:
- error_code:
- m_exit(M_NOVAR);
- }
- return(buff);
- }
- /*}}} */
-
- public TOKEN *parse_term(tokens token,TOKEN *buff,int dest,int dummy_base,boolean *ret_used)
- { DEST_DAT t;
-
- start_dest_handle(&t,dest,&buff,&dummy_base);
- buff=rpt(token,buff,dest,dummy_base+1,ret_used,&t);
- end_dest_handle(&t);
-
- return(buff);
- }
- /*}}} */
- /*{{{ get_message*/
- public TOKEN *get_message(TOKEN *buff)
- {
- tokens read=get_full_token();
- TOKEN *x=tk_macro;
-
- if (read!=MACRO)
- /*{{{ complex prompt ( ... ))*/
- { if (read!=BEGIN)
- m_exit(M_NOMESSAGE);
- while ((read=get_full_token())!=END)
- /*{{{ handle message entry*/
- switch (read)
- { case MACRO:
- /*{{{ copy the string*/
- { TOKEN *x;
-
- for (x=tk_macro;*x;*buff++ = *x++);
- break;
- }
- /*}}} */
- case NUMBER:
- /*{{{ code the character directly*/
- *buff++=tk_val;
- break;
- /*}}} */
- case HISTORY:
- /*{{{ put history code*/
- *buff++=M_GET_HISTORY;
- if ((*buff++=(TOKEN)name_to_history(get_full_token(),False))==(TOKEN)unknown_history)
- m_exit(M_NOHISTORY);
- break;
- /*}}} */
- case COUNTER:
- /*{{{ put var*/
- *buff++ = M_INT_STRING;
- if (!(buff=put_var(buff))) return(0);
- break;
- /*}}} */
- case NAME:
- /*{{{ search for the message*/
- { int msg_no;
-
- if ((msg_no=name2msg(tk_string))>=0)
- { *buff++=(-msg_no);
- break;
- }
- }
- /*}}} */
- default:
- m_exit(M_WANTEND);
- }
- /*}}} */
- }
- /*}}} */
- else
- while (*x) *buff++ = *x++;
- return(buff);
- }
- /*}}} */
-