home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
jed207.lha
/
src
/
jed.lha
/
scriptcmds.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-06
|
17KB
|
826 lines
/*
* SCRIPTCMDS.C
* (c) 1992-3 J.Harper
*/
#include "jed.h"
#include "jed_protos.h"
Prototype VALUE * cmd_script (LONG, VALUE *);
Prototype VALUE * cmd_nargs (LONG, VALUE *);
Prototype VALUE * cmd_arg (LONG, VALUE *);
Prototype VALUE * cmd_if (LONG, VALUE *);
Prototype VALUE * cmd_while (LONG, VALUE *);
Prototype VALUE * cmd_select (LONG, VALUE *);
Prototype VALUE * cmd_dowhile (LONG, VALUE *);
Prototype VALUE * cmd_return (LONG, VALUE *);
Prototype VALUE * cmd_break (LONG, VALUE *);
Prototype VALUE * cmd_addsym (LONG, VALUE *);
Prototype VALUE * cmd_remsym (LONG, VALUE *);
Prototype VALUE * cmd_renamesym (LONG, VALUE *);
Prototype VALUE * cmd_export (LONG, VALUE *);
Prototype VALUE * cmd_type (LONG, VALUE *);
Prototype VALUE * cmd_plus (LONG, VALUE *);
Prototype VALUE * cmd_minus (LONG, VALUE *);
Prototype VALUE * cmd_product (LONG, VALUE *);
Prototype VALUE * cmd_divide (LONG, VALUE *);
Prototype VALUE * cmd_mod (LONG, VALUE *);
Prototype VALUE * cmd_b_not (LONG, VALUE *);
Prototype VALUE * cmd_l_not (LONG, VALUE *);
Prototype VALUE * cmd_b_or (LONG, VALUE *);
Prototype VALUE * cmd_l_or (LONG, VALUE *);
Prototype VALUE * cmd_b_and (LONG, VALUE *);
Prototype VALUE * cmd_l_and (LONG, VALUE *);
Prototype VALUE * cmd_b_eor (LONG, VALUE *);
Prototype VALUE * cmd_l_eor (LONG, VALUE *);
Prototype VALUE * cmd_lshift (LONG, VALUE *);
Prototype VALUE * cmd_rshift (LONG, VALUE *);
Prototype VALUE * cmd_equals (LONG, VALUE *);
Prototype VALUE * cmd_equality (LONG, VALUE *);
Prototype VALUE * cmd_inequality (LONG, VALUE *);
Prototype VALUE * cmd_gtthan (LONG, VALUE *);
Prototype VALUE * cmd_ltthan (LONG, VALUE *);
Prototype VALUE * cmd_gethan (LONG, VALUE *);
Prototype VALUE * cmd_lethan (LONG, VALUE *);
Prototype VALUE * cmd_nop (LONG, VALUE *);
/*
* (script `sectType')
* (script `x' `file') - x stands for external (f is a section type)
*/
VALUE *
cmd_script(LONG argc, VALUE *argv)
{
if(TPLATE2(VTF_STRING, VTF_ANY))
{
if(*(ARG1.val_Value.String) == 'x')
{
if(ARG2.val_Type == VTF_STRING)
{
STRPTR file;
if(!(file = squirrelfile(ARG2.val_Value.String)))
{
UBYTE othername[200];
strcpy(othername, "s:jed/");
AddPart(othername, ARG2.val_Value.String, 200);
file = squirrelfile(othername);
}
if(file)
{
if(!execstr(file, &RES, FALSE, 0, NULL))
{
freestring(file);
return(FALSE);
}
freestring(file);
}
else
doserror();
}
else
settitle("syntax error: argument 2 should be a string.");
}
else if(*(ARG1.val_Value.String) == 's')
{
if(ARG2.val_Type == VTF_STRING)
{
if(!execstr(ARG2.val_Value.String, &RES, FALSE, 0, NULL))
return(FALSE);
}
else
settitle("syntax error: argument 2 should be a string.");
}
else
{
POS temp = CurrVW->vw_CursorPos;
POS endpos;
if(getsection(ARG1.val_Value.String, &endpos))
{
POS startpos = CurrVW->vw_CursorPos;
LONG length;
STRPTR text;
CurrVW->vw_CursorPos = temp;
length = sectionlength(&startpos, &endpos);
if(text = AllocVec(length + 1, 0L))
{
copysection(&startpos, &endpos, text);
text[length] = 0;
if(!execstr(text, &RES, FALSE, 0, NULL))
{
FreeVec(text);
return(FALSE);
}
FreeVec(text);
}
else
settitle(NoMemMsg);
}
}
}
return(&RES);
}
/*
* returns the number of arguments passed to the innermost macro
* (nargs)
*/
VALUE *
cmd_nargs(LONG argc, VALUE *argv)
{
LONG xargc;
VALUE *xargv;
if(findsargs(&xargc, &xargv))
{
setnumres(xargc);
}
return(&RES);
}
/*
* returns an argument (prompts for it if it wasn't given)
* (arg n `type' [`prompt'])
*
* type defines the type of value required -- `s' = string, `n' = number.
* `e' = either
* if an argument of the proper type can't be got then the macro is
* aborted.
*/
VALUE *
cmd_arg(LONG argc, VALUE *argv)
{
VALUE *res = &RES;
if(TPLATE2(VTF_NUMBER, VTF_STRING))
{
LONG xargc;
VALUE *xargv;
if(findsargs(&xargc, &xargv))
{
LONG argnum = ARG1.val_Value.Number;
switch(*(ARG2.val_Value.String))
{
case 'e':
dupvalue(&RES, &xargv[argnum]);
break;
case 's':
STRPTR arg = NULL;
if(xargv[argnum].val_Type == VTF_STRING)
dupvalue(&RES, &xargv[argnum]);
else
{
if(ARG3.val_Type == VTF_STRING)
arg = docmdline(ARG3.val_Value.String);
else
arg = docmdline("string> ");
if(argc)
{
setstrres(arg);
}
}
break;
case 'n':
STRPTR str;
if(xargv[argnum].val_Type == VTF_NUMBER)
dupvalue(&RES, &xargv[argnum]);
else
{
if(ARG3.val_Type == VTF_STRING)
str = docmdline(ARG3.val_Value.String);
else
str = docmdline("number> ");
if(str)
{
if(isdigit(*str) || (*str == '-'))
{
APTR dummy;
setnumres(strtol(str, &dummy, 0));
}
freestring(str);
}
}
break;
}
if(RES.val_Type == VTF_NONE)
{
settitlefmt("syntax error: no arg %ld provided", ARG1.val_Value.Number);
res = FALSE;
}
}
else
{
settitle("error: not in macro - can't use arg command");
res = FALSE;
}
}
else
res = FALSE;
return(res);
}
/*
* (if condition-clause `true-clause' `false-clause')
*
* result is value of evaluated clause.
*/
VALUE *
cmd_if(LONG argc, VALUE *argv)
{
if(TPLATE3(VTF_NUMBER, VTF_ANY, VTF_ANY))
{
if(ARG1.val_Value.Number)
{
if(ARG2.val_Type == VTF_STRING)
{
if(!execstr(ARG2.val_Value.String, &RES, FALSE, 0, NULL))
return(FALSE);
}
}
else
{
if(ARG3.val_Type == VTF_STRING)
{
if(!execstr(ARG3.val_Value.String, &RES, FALSE, 0, NULL))
return(FALSE);
}
}
}
return(&RES);
}
/*
* (while `condition-clause' `true-clause')
*
* result is number of iterations before stopping.
* loop will be broken after MAX_ITS number of iterations or a ^C break
* signal is received.
*/
#define MAX_ITS (1000000)
VALUE *
cmd_while(LONG argc, VALUE *argv)
{
if(TPLATE2(VTF_STRING, VTF_STRING))
{
LONG i;
for(i = 0; i < MAX_ITS; i++)
{
VALUE value;
if(!execstr(ARG1.val_Value.String, &value, FALSE, 0, NULL))
{
releasevalue(&value);
return(FALSE);
}
if(!value.val_Value.Number)
{
releasevalue(&value);
setnumres(i);
return(&RES);
}
releasevalue(&value);
if(!execstr(ARG2.val_Value.String, &value, FALSE, 0, NULL))
{
releasevalue(&value);
return(FALSE);
}
releasevalue(&value);
if(CheckSignal(SIGBREAKF_CTRL_C))
{
settitle("^C: while aborted");
break;
}
}
if(i == MAX_ITS)
settitle("wow... a million iterations, while loop aborted");
}
return(FALSE);
}
/*
* (select
* (cond1)
* `reaction1'
* (cond2)
* `reaction2'
* ...
* `default'
* )
*/
VALUE *
cmd_select(LONG argc, VALUE *argv)
{
VALUE *res;
WORD i;
for(i = 0; i < argc; i += 2)
{
if((argv[i + 1].val_Type == VTF_NUMBER) && (argv[i + 2].val_Type == VTF_STRING))
{
if(argv[i + 1].val_Value.Number)
return(execstr(argv[i + 2].val_Value.String, &RES, FALSE, 0, NULL));
}
else if(argv[i + 1].val_Type == VTF_STRING)
return(execstr(argv[i + 1].val_Value.String, &RES, FALSE, 0, NULL));
}
return(&RES);
}
/*
* (dowhile `command' `condition')
*
* similar to a C 'do...while' loop.
*/
VALUE *
cmd_dowhile(LONG argc, VALUE *argv)
{
if(TPLATE2(VTF_STRING, VTF_STRING))
{
LONG i;
for(i = 0; i < MAX_ITS; i++)
{
VALUE value;
if(!execstr(ARG1.val_Value.String, &value, FALSE, 0, NULL))
{
releasevalue(&value);
return(FALSE);
}
releasevalue(&value);
if(!execstr(ARG2.val_Value.String, &value, FALSE, 0, NULL))
{
releasevalue(&value);
return(FALSE);
}
if(!value.val_Value.Number)
{
releasevalue(&value);
setnumres(i);
return(&RES);
}
if(CheckSignal(SIGBREAKF_CTRL_C))
{
settitle("^C: dowhile aborted");
break;
}
}
if(i == MAX_ITS)
settitle("wow... a million iterations, dowhile loop aborted");
}
return(FALSE);
}
/*
* breaks from the macro, returns ARG1
*/
VALUE *
cmd_return(LONG argc, VALUE *argv)
{
dupvalue(&RES, &ARG1);
return(FALSE);
}
/*
* (break n)
* Breaks out of n depths of strings that are currently being executed.
*/
VALUE *
cmd_break(LONG argc, VALUE *argv)
{
RES.val_Type = VTF_BREAK;
if(ARG1.val_Type == VTF_NUMBER)
{
if((RES.val_Value.Number = ARG1.val_Value.Number) <= 0)
{
RES.val_Type = VTF_NONE;
return(&RES);
}
}
else
RES.val_Value.Number = 1;
return(FALSE);
}
/*
* (addsym {`sym-name' value symbol-type})
*
* symbol-type is,
* 1 -- global command
* 2 -- global variable
* 3 -- local command
* 4 -- local variable
*/
VALUE *
cmd_addsym(LONG argc, VALUE *argv)
{
VALUE *res = &RES;
BOOL rc = TRUE;
while(rc && (argc >= 3))
{
if(TPLATE3(VTF_STRING, VTF_ANY, VTF_NUMBER))
{
if(ARG3.val_Value.Number <= 2)
{
if(!addgsym(ARG1.val_Value.String, ARG3.val_Value.Number, &ARG2))
rc = FALSE;
}
else
{
if(!addlsym(ARG1.val_Value.String, ARG3.val_Value.Number - 2, &ARG2))
rc = FALSE;
}
if(!rc)
settitlefmt("error: can't create variable %s", (LONG)ARG1.val_Value.String);
}
else
goto abort;
argc -= 3;
argv += 3;
}
res->val_Type = VTF_NUMBER;
res->val_Value.Number = rc;
abort:
return(res);
}
/*
* (remsym {`sym-name'})
*
* note that if you want you can remove the primitive commands!
*/
VALUE *
cmd_remsym(LONG argc, VALUE *argv)
{
VALUE *res = &RES;
BOOL rc = TRUE;
while(rc && (argc >= 1))
{
if(TPLATE1(VTF_STRING))
{
if(!remsym(ARG1.val_Value.String))
{
settitlefmt("error: can't remove symbol %s", (LONG)ARG1.val_Value.String);
rc = FALSE;
}
}
else
goto abort;
argc--;
argv++;
}
res->val_Type = VTF_NUMBER;
res->val_Value.Number = rc;
abort:
return(res);
}
/*
* (renamesym {`old-name' `new-name'})
*
* This can be used to rename primitive commands so that a macro can sit
* on top of it.
*/
VALUE *
cmd_renamesym(LONG argc, VALUE *argv)
{
VALUE *res = &RES;
BOOL rc = TRUE;
while(rc && (argc >= 2))
{
if(TPLATE2(VTF_STRING, VTF_STRING))
{
GSYM *sym;
if(sym = findgsym(ARG1.val_Value.String))
{
STRPTR newname;
if(newname = savestring(ARG2.val_Value.String))
{
removehash(SymbolTab, &sym->gs_Node, GSYMTABSIZE);
freestring(sym->gs_Node.h_Name);
sym->gs_Node.h_Name = newname;
inserthash(SymbolTab, &sym->gs_Node, GSYMTABSIZE);
}
else
{
settitle(NoMemMsg);
rc = FALSE;
}
}
else
{
settitlefmt("error: no symbol %s", (LONG)ARG1.val_Value.String);
rc = FALSE;
}
}
else
goto abort;
argc -= 2;
argv += 2;
}
res->val_Type = VTF_NUMBER;
res->val_Value.Number = rc;
abort:
return(res);
}
/*
* (export {`lsym' how-far})
*
* moves lsym from its current depth to (current_depth - how_far)
*/
VALUE *
cmd_export(LONG argc, VALUE *argv)
{
VALUE *res = &RES;
BOOL rc = TRUE;
while(rc && (argc >= 2))
{
if(TPLATE2(VTF_STRING, VTF_NUMBER))
{
LSYM *ls = NULL;
WORD i;
for(i = CSDepth; !ls && i; i--)
{
for(ls = (LSYM *)CSList[i].cs_Locals.lh_Head; ls->ls_Node.ln_Succ; ls = (LSYM *)ls->ls_Node.ln_Succ)
{
if(!strcmp(ARG1.val_Value.String, ls->ls_Node.ln_Name))
break;
}
}
i -= ARG2.val_Value.Number;
if(ls && (i > 0))
{
Remove(&ls->ls_Node);
AddTail(&CSList[i].cs_Locals, &ls->ls_Node);
}
else
{
settitlefmt("error: no local symbol %s", (LONG)ARG1.val_Value.String);
rc = FALSE;
}
}
else
goto abort;
argc -= 2;
argv += 2;
}
res->val_Type = VTF_NUMBER;
res->val_Value.Number = rc;
abort:
return(res);
}
/*
* (type <value>)
*/
VALUE *
cmd_type(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Type);
return(&RES);
}
/*
* some arithmetic commands
*/
/* (+ 1 2) */
VALUE *
cmd_plus(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number + ARG2.val_Value.Number);
return(&RES);
}
/* (- 1 [2]) */
VALUE *
cmd_minus(LONG argc, VALUE *argv)
{
if(argc == 1)
setnumres(-(ARG1.val_Value.Number));
else
setnumres(ARG1.val_Value.Number - ARG2.val_Value.Number);
return(&RES);
}
/* (* 1 2) */
VALUE *
cmd_product(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number * ARG2.val_Value.Number);
return(&RES);
}
/* (/ 1 2) */
VALUE *
cmd_divide(LONG argv, VALUE *argv)
{
setnumres(ARG1.val_Value.Number / ARG2.val_Value.Number);
return(&RES);
}
/* (% 1 2) */
VALUE *
cmd_mod(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number % ARG2.val_Value.Number);
return(&RES);
}
/* (~ 1) */
VALUE *
cmd_b_not(LONG argc, VALUE *argv)
{
setnumres(~ARG1.val_Value.Number);
return(&RES);
}
/* (! 1) */
VALUE *
cmd_l_not(LONG argc, VALUE *argv)
{
setnumres(!ARG1.val_Value.Number);
return(&RES);
}
/* (| 1 2) */
VALUE *
cmd_b_or(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number | ARG2.val_Value.Number);
return(&RES);
}
/* (|| 1 2) */
VALUE *
cmd_l_or(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number || ARG2.val_Value.Number);
return(&RES);
}
/* (& 1 2) */
VALUE *
cmd_b_and(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number & ARG2.val_Value.Number);
return(&RES);
}
/* (&& 1 2) */
VALUE *
cmd_l_and(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number && ARG2.val_Value.Number);
return(&RES);
}
/* (^ 1 2) */
VALUE *
cmd_b_eor(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number ^ ARG2.val_Value.Number);
return(&RES);
}
/* (^^ 1 2) */
VALUE *
cmd_l_eor(LONG argc, VALUE *argv)
{
if(ARG1.val_Value.Number)
{
if(ARG2.val_Value.Number)
setnumres(FALSE);
else
setnumres(TRUE);
}
else
setnumres(TRUE);
return(&RES);
}
/* (<< 1 2) */
VALUE *
cmd_lshift(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number << ARG2.val_Value.Number);
return(&RES);
}
/* (>> 1 2) */
VALUE *
cmd_rshift(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number >> ARG2.val_Value.Number);
return(&RES);
}
/*
* (= `varname' value)
*/
VALUE *
cmd_equals(LONG argc, VALUE *argv)
{
if(TPLATE2(VTF_STRING, VTF_ANY))
{
LSYM *lsym;
GSYM *gsym;
BOOL rc = TRUE;
if(lsym = findlsym(ARG1.val_Value.String))
{
releasevalue(&lsym->ls_Sym.sym_Value);
if(!dupvalue(&lsym->ls_Sym.sym_Value, &ARG2))
rc = FALSE;
}
else if(gsym = findgsym(ARG1.val_Value.String))
{
releasevalue(&gsym->gs_Sym.sym_Value);
if(!dupvalue(&gsym->gs_Sym.sym_Value, &ARG2))
rc = FALSE;
}
else
{
if(!addlsym(ARG1.val_Value.String, STF_VARIABLE, &ARG2))
rc = FALSE;
}
if(!rc)
settitlefmt("error: can't set symbol %s", (LONG)ARG1.val_Value.String);
setnumres(rc);
}
return(&RES);
}
/*
* comparison operators
*/
/*
* (== `string1' `STRING2')
* (== 1 2)
*/
VALUE *
cmd_equality(LONG argc, VALUE *argv)
{
if((ARG1.val_Type == VTF_STRING) && (ARG2.val_Type == VTF_STRING))
setnumres(!stricmp(ARG1.val_Value.String, ARG2.val_Value.String));
else if((ARG1.val_Type == VTF_NUMBER) && (ARG2.val_Type == VTF_NUMBER))
setnumres(ARG1.val_Value.Number == ARG2.val_Value.Number);
else
settitle("syntax error: incorrect arguments to ==");
return(&RES);
}
/*
* (!= `string1' `STRING2')
* (!= 1 2)
*/
VALUE *
cmd_inequality(LONG argc, VALUE *argv)
{
if((ARG1.val_Type == VTF_STRING) && (ARG2.val_Type == VTF_STRING))
setnumres(stricmp(ARG1.val_Value.String, ARG2.val_Value.String));
else if((ARG1.val_Type == VTF_NUMBER) && (ARG2.val_Type == VTF_NUMBER))
setnumres(ARG1.val_Value.String != ARG2.val_Value.String);
else
settitle("syntax error: incorrect arguments to !=");
return(&RES);
}
/* (> 1 2) */
VALUE *
cmd_gtthan(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number > ARG2.val_Value.Number);
return(&RES);
}
/* (< 1 2) */
VALUE *
cmd_ltthan(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number < ARG2.val_Value.Number);
return(&RES);
}
/* (>= 1 2) */
VALUE *
cmd_gethan(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number >= ARG2.val_Value.Number);
return(&RES);
}
/* (<= 1 2) */
VALUE *
cmd_lethan(LONG argc, VALUE *argv)
{
setnumres(ARG1.val_Value.Number <= ARG2.val_Value.Number);
return(&RES);
}
/*
* (nop)
*/
VALUE *
cmd_nop(LONG argc, VALUE *argv)
{
setnumres(FALSE);
return(&RES);
}