Commit e5427170 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl

Fri Jul 24 16:01:28 2009 Jiri (George) Lebl <jirka@5z.com>

	* src/calc.c, src/compil.c: Correctly compile/decompile all the new
	  function attributes

	* src/calc.c: correctly print out the local stuff, handle local node
	  correctly when outside of functions

	* src/funclib.c, src/graphing.c: handle eof errors from parsing
	  things correctly without dying.

	* src/dict.c, src/eval.c, src/structs.h: is_local generally should
	  not be moved around with the function.  Also correctly copy/free
	  all the other attributes when needed as well.

	* src/eval.c: Set arguments BEFORE extradict.  This should never
	  be an issue, but it feels more correct.

	* src/dict.c: when the subst list becomes empty, remove from subst
	  list to avoid unnecessary lookups

	* lib/*/*.gel: update and fix for the [] operator

	* src/geniustests.txt: Add some testcases

	* src/symbolic.c: just a comment change
parent 094e9ebf
Fri Jul 24 16:01:28 2009 Jiri (George) Lebl <jirka@5z.com>
* src/calc.c, src/compil.c: Correctly compile/decompile all the new
function attributes
* src/calc.c: correctly print out the local stuff, handle local node
correctly when outside of functions
* src/funclib.c, src/graphing.c: handle eof errors from parsing
things correctly without dying.
* src/dict.c, src/eval.c, src/structs.h: is_local generally should
not be moved around with the function. Also correctly copy/free
all the other attributes when needed as well.
* src/eval.c: Set arguments BEFORE extradict. This should never
be an issue, but it feels more correct.
* src/dict.c: when the subst list becomes empty, remove from subst
list to avoid unnecessary lookups
* lib/*/*.gel: update and fix for the [] operator
* src/geniustests.txt: Add some testcases
* src/symbolic.c: just a comment change
Thu Jul 23 18:35:28 2009 Jiri (George) Lebl <jirka@5z.com>
* src/parse.y, src/eval.c, src/dict.c, src/structs.h: Add an optional
......
-- check fourier stuff
-- document new things in 1.0.7
-- check modified functions in the library
* Logfiles and/or save session
* Whack the readline nonsense in the GUI
* Native polynomial operation
......
......@@ -128,7 +128,7 @@ function NumericalDerivative(f,x0) =
(
local *;
# FIXME: perhaps check differentiability first, but then we're doing so many limits already
NumericalLimitAtInfinity (`(n)=(TwoSidedFivePointFormula(f,x0,2.0^(-n))),
NumericalLimitAtInfinity (`(n)[f,x0]=(TwoSidedFivePointFormula(f,x0,2.0^(-n))),
Identity,
DerivativeTolerance,
DerivativeSFS,
......@@ -141,7 +141,7 @@ NDerivative = NumericalDerivative
function NumericalLeftDerivative(f,x0) =
(
local *;
NumericalLimitAtInfinity (`(n)=(OneSidedFivePointFormula(f,x0,-(2.0^(-n)))),
NumericalLimitAtInfinity (`(n)[f,x0]=(OneSidedFivePointFormula(f,x0,-(2.0^(-n)))),
Identity,
DerivativeTolerance,
DerivativeSFS,
......@@ -152,7 +152,7 @@ SetHelp("NumericalLeftDerivative","calculus","Attempt to calculate numerical lef
function NumericalRightDerivative(f,x0) =
(
local *;
NumericalLimitAtInfinity (`(n)=(OneSidedFivePointFormula(f,x0,2.0^(-n))),
NumericalLimitAtInfinity (`(n)[f,x0]=(OneSidedFivePointFormula(f,x0,2.0^(-n))),
Identity,
DerivativeTolerance,
DerivativeSFS,
......
......@@ -65,4 +65,7 @@ SetHelp ("NumericalIntegralFunction", "parameters", "The function used for numer
parameter NumericalIntegralFunction = `CompositeSimpsonsRule
SetHelp ("NumericalIntegral", "calculus", "Integration by rule set in NumericalIntegralFunction of f from a to b using NumericalIntegralSteps steps")
function NumericalIntegral(f,a,b) = (local *;NumericalIntegralFunction call (f,a,b,NumericalIntegralSteps))
function NumericalIntegral(f,a,b) = (
local *;
NumericalIntegralFunction call (f,a,b,NumericalIntegralSteps)
)
......@@ -21,8 +21,8 @@
# Limits:
SetHelp ("NumericalLimitAtInfinity", "calculus", "Attempt to calculate the limit of f(step_fun(i)) as i goes from 1 to N")
function NumericalLimitAtInfinity(_f,step_fun,tolerance,successive_for_success,N) =
# this evaluates _f(step_fun(i)) as i goes from 1 to N.
function NumericalLimitAtInfinity(f,step_fun,tolerance,successive_for_success,N) =
# this evaluates f(step_fun(i)) as i goes from 1 to N.
# If s_f_s of the pairwise successive differences are less than tolerance, then
# it returns the last value; if this doesn't happen, it returns Null.
# INPUT: N had better be at least 1
......@@ -30,10 +30,10 @@ function NumericalLimitAtInfinity(_f,step_fun,tolerance,successive_for_success,N
# bounded oscillation (like sin(x))
(
local *;
current_limit = _f(step_fun(1));
current_limit = f(step_fun(1));
number_of_consecutive_differences_within_tolerance = 0;
for i = 2 to N do (
new_limit = _f(step_fun(i));
new_limit = f(step_fun(i));
if (|new_limit-current_limit| < tolerance) then (
number_of_consecutive_differences_within_tolerance = number_of_consecutive_differences_within_tolerance+1
) else (
......
......@@ -96,7 +96,7 @@ function Multinomial(v,arg...) = (
else
m = [v, arg];
MatrixSum(m)!/MatrixProduct(ApplyOverMatrix(m,`(x)=x!))
MatrixSum(m)!/MatrixProduct(ApplyOverMatrix(m,`(x)[]=x!))
)
SetHelp("Pascal","combinatorics","Get the pascal's triangle as a matrix");
......
......@@ -14,13 +14,13 @@ function Hofstadter(n) = (
(error("Hofstadter: argument not a positive integer");bailout);
# reason for doing this is that it's just plain faster then calling self
# again
function _h (n) = (
function h (n) = (
if n <= 2 then
1
else
_h(n - _h(n-1)) + _h(n - _h(n-2))
h(n - h(n-1)) + h(n - h(n-2))
);
_h (n)
h (n)
)
......
......@@ -30,10 +30,10 @@ function VectorAngle(v,w,B...) =
#FIXME: check parameters
SetHelp ("BilinearFormFunction", "linear_algebra", "Return a function that evaluates two vectors with respect to the bilinear form given by A")
function BilinearFormFunction(A)=(`(v,w)=(v.'*A*w)@(1))
function BilinearFormFunction(A)=(`(v,w)[A]=(v.'*A*w)@(1))
SetHelp ("SesquilinearFormFunction", "linear_algebra", "Return a function that evaluates two vectors with respect to the sesquilinear form given by A")
function SesquilinearFormFunction(A)=(`(v,w)=(v'*A*w)@(1))
function SesquilinearFormFunction(A)=(`(v,w)[A]=(v'*A*w)@(1))
# Projection onto a vector space
# Projection of vector v onto subspace W given a sesquilinear form B
......@@ -65,7 +65,7 @@ function GramSchmidt(v,B...) =
# if you don't give anything, assume standard inner product
if IsNull(B) or IsNull(B@(1)) then P=HermitianProduct
# If it's a matrix, then use the sesquilinear form defined by that matrix
else if IsMatrix(B@(1)) then (function P(u,w)=SesquilinearForm(u,B@(1),w))
else if IsMatrix(B@(1)) then (function P(u,w)[B]=SesquilinearForm(u,B@(1),w))
# If B is just some function, assume that it's an inner product
else if elements(B) > 1 or not IsFunction(B@(1)) then (error("GramSchmidt: argument B not a function or Matrix");bailout)
else P = B@(1);
......
......@@ -38,7 +38,7 @@ SetHelp("SymbolicNthDerivativeTry","symbolic","Attempt to symbolically different
function SymbolicTaylorApproximationFunction(f,x0,n) =
(
local f,df,c,n,k;
local *;
if not IsFunction(f) then
(error("SymbolicTaylorApproximationFunction: argument 1 must be a function");bailout)
else if not IsValue(x0) then
......@@ -58,6 +58,6 @@ function SymbolicTaylorApproximationFunction(f,x0,n) =
)
);
tp = PolyToFunction (c);
`(x) = (tp call (x - x0))
`(x)[tp,x0] = (tp call (x - x0))
)
SetHelp("SymbolicTaylorApproximationFunction","symbolic","Attempt to construct the taylor approximation function around x0 to the nth degree.");
......@@ -1318,12 +1318,29 @@ append_func (GelOutput *gelo, GelEFunc *f)
if (f->vararg)
gel_output_string (gelo, "...");
if G_LIKELY (f->type==GEL_USER_FUNC) {
if G_LIKELY (f->type == GEL_USER_FUNC) {
gel_output_string(gelo,")=");
D_ENSURE_USER_BODY (f);
if (f->extra_dict != NULL ||
f->local_all ||
f->local_idents != NULL) {
gel_output_string(gelo,"(");
}
if (f->local_all) {
gel_output_string(gelo,"local *;");
} else if (f->local_idents != NULL) {
GSList *li;
gel_output_string(gelo,"local ");
for (li = f->local_idents; li != NULL; li = li->next) {
GelToken *tok = li->data;
if (li != f->local_idents)
gel_output_string(gelo,",");
gel_output_string (gelo, tok->token);
}
gel_output_string(gelo,";");
}
if (f->extra_dict != NULL) {
GSList *li;
gel_output_string(gelo,"(");
for (li = f->extra_dict; li != NULL; li = li->next) {
GelEFunc *ff = li->data;
gel_output_string (gelo, ff->id->token);
......@@ -1337,7 +1354,9 @@ append_func (GelOutput *gelo, GelEFunc *f)
}
}
gel_print_etree (gelo, f->data.user, FALSE);
if (f->extra_dict != NULL) {
if (f->extra_dict != NULL ||
f->local_all ||
f->local_idents != NULL) {
gel_output_string(gelo,")");
}
gel_output_string(gelo,")");
......@@ -1821,13 +1840,36 @@ compile_funcs_in_dict (FILE *outfile, GSList *dict, gboolean is_extra_dict)
}
if (func->type == GEL_USER_FUNC) {
fprintf (outfile,
"%c;%d;%s;%s;%d;%d",
"%c;%d;%s;%s;n%d;v%d;p%d;o%d;l%d;e%d;b%d",
fs,
(int)strlen (body),
func->id->token,
func->symbolic_id ? func->symbolic_id->token : "*",
(int)func->nargs,
(int)func->vararg);
(int)func->vararg,
(int)func->propagate_mod,
(int)func->no_mod_all_args,
(int)func->local_all,
(int)func->never_on_subst_list,
(int)func->built_subst_dict);
if (func->local_idents == NULL)
fprintf (outfile, ";-");
for (l = func->local_idents; l != NULL; l = l->next) {
GelToken *tok = l->data;
if (l != func->local_idents)
fprintf (outfile, ",%s", tok->token);
else
fprintf (outfile, ";%s", tok->token);
}
if (func->subst_dict == NULL)
fprintf (outfile, ";-");
for (l = func->subst_dict; l != NULL; l = l->next) {
GelToken *tok = l->data;
if (l != func->subst_dict)
fprintf (outfile, ",%s", tok->token);
else
fprintf (outfile, ";%s", tok->token);
}
for (l = func->named_args; l != NULL; l = l->next) {
GelToken *tok = l->data;
fprintf (outfile, ";%s", tok->token);
......@@ -1902,6 +1944,8 @@ gel_compile_all_user_funcs (FILE *outfile)
g_slist_free (funcs);
}
/* FIXME: function reading is almost identical to that for FUNCTION_NODEs
in compile.c We should really unify these! */
static void
load_compiled_fp (const char *file, FILE *fp)
{
......@@ -1939,7 +1983,9 @@ load_compiled_fp (const char *file, FILE *fp)
char *p;
char *b2;
GelToken *tok, *symbolic_tok = NULL;
int size, nargs, vararg;
int size, nargs, vararg, propagate_mod, no_mod_all_args;
int local_all, never_on_subst_list, built_subst_dict;
GSList *local_idents, *subst_dict;
gboolean extra_dict = FALSE;
gboolean parameter = FALSE;
int i;
......@@ -2107,7 +2153,7 @@ load_compiled_fp (const char *file, FILE *fp)
continue;
}
nargs = -1;
sscanf(p,"%d",&nargs);
sscanf(p,"n%d",&nargs);
if G_UNLIKELY (nargs == -1) {
gel_errorout (_("Badly formed record"));
continue;
......@@ -2120,12 +2166,109 @@ load_compiled_fp (const char *file, FILE *fp)
continue;
}
vararg = -1;
sscanf(p,"%d",&vararg);
sscanf(p,"v%d",&vararg);
if G_UNLIKELY (vararg == -1) {
gel_errorout (_("Badly formed record"));
continue;
}
/*propagate_mod*/
p = strtok_r (NULL,";", &ptrptr);
if (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
propagate_mod = -1;
sscanf(p,"p%d",&propagate_mod);
if G_UNLIKELY (propagate_mod == -1) {
gel_errorout (_("Badly formed record"));
continue;
}
/*no_mod_all_args*/
p = strtok_r (NULL,";", &ptrptr);
if (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
no_mod_all_args = -1;
sscanf(p,"o%d",&no_mod_all_args);
if G_UNLIKELY (no_mod_all_args == -1) {
gel_errorout (_("Badly formed record"));
continue;
}
/*local_all*/
p = strtok_r (NULL,";", &ptrptr);
if (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
local_all = -1;
sscanf(p,"l%d",&local_all);
if G_UNLIKELY (local_all == -1) {
gel_errorout (_("Badly formed record"));
continue;
}
/*never_on_subst_list*/
p = strtok_r (NULL,";", &ptrptr);
if (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
never_on_subst_list = -1;
sscanf(p,"e%d",&never_on_subst_list);
if G_UNLIKELY (never_on_subst_list == -1) {
gel_errorout (_("Badly formed record"));
continue;
}
/*built_subst_list*/
p = strtok_r (NULL,";", &ptrptr);
if (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
built_subst_dict = -1;
sscanf(p,"b%d",&built_subst_dict);
if G_UNLIKELY (built_subst_dict == -1) {
gel_errorout (_("Badly formed record"));
continue;
}
/*local_idents*/
p = strtok_r (NULL,";", &ptrptr);
if G_UNLIKELY (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
local_idents = NULL;
if (strcmp (p, "-") != 0) {
char **s;
s = g_strsplit (p, ",", -1);
for (i = 0; s[i] != NULL; i++) {
local_idents = g_slist_append (local_idents, d_intern (s[i]));
}
g_strfreev (s);
}
/*subst_dict*/
p = strtok_r (NULL,";", &ptrptr);
if G_UNLIKELY (p == NULL) {
gel_errorout (_("Badly formed record"));
continue;
}
subst_dict = NULL;
if (strcmp (p, "-") != 0) {
char **s;
s = g_strsplit (p, ",", -1);
for (i = 0; s[i] != NULL; i++) {
subst_dict = g_slist_append (subst_dict, d_intern (s[i]));
}
g_strfreev (s);
}
/*argument names*/
li = NULL;
for(i=0;i<nargs;i++) {
......@@ -2170,6 +2313,13 @@ load_compiled_fp (const char *file, FILE *fp)
func = d_makeufunc (tok, NULL, li, nargs, NULL);
func->vararg = vararg ? 1 : 0;
func->symbolic_id = symbolic_tok;
func->propagate_mod = propagate_mod ? 1 : 0;
func->no_mod_all_args = no_mod_all_args ? 1 : 0;
func->local_all = local_all ? 1 : 0;
func->never_on_subst_list = never_on_subst_list ? 1 : 0;
func->built_subst_dict = built_subst_dict ? 1 : 0;
func->subst_dict = subst_dict;
func->local_idents = local_idents;
} else /*GEL_VARIABLE_FUNC*/ {
func = d_makevfunc (tok, NULL);
}
......@@ -2186,6 +2336,13 @@ load_compiled_fp (const char *file, FILE *fp)
func = d_makeufunc (tok, NULL, li, nargs, NULL);
func->vararg = vararg ? 1 : 0;
func->symbolic_id = symbolic_tok;
func->propagate_mod = propagate_mod ? 1 : 0;
func->no_mod_all_args = no_mod_all_args ? 1 : 0;
func->local_all = local_all ? 1 : 0;
func->never_on_subst_list = never_on_subst_list ? 1 : 0;
func->built_subst_dict = built_subst_dict ? 1 : 0;
func->subst_dict = subst_dict;
func->local_idents = local_idents;
} else /*GEL_VARIABLE_FUNC*/ {
func = d_makevfunc(tok,NULL);
}
......@@ -3140,18 +3297,32 @@ gel_parseexp (const char *str, FILE *infile, gboolean exec_commands,
stacklen = g_slist_length(gel_parsestack);
if(stacklen==0) {
if(finished) *finished = FALSE;
if (stacklen == 0) {
if (finished != NULL)
*finished = FALSE;
return NULL;
}
/*stack is supposed to have only ONE entry*/
if(stacklen!=1) {
while(gel_parsestack)
gel_freetree(gel_stack_pop(&gel_parsestack));
if (stacklen != 1) {
while (gel_parsestack != NULL)
gel_freetree (gel_stack_pop (&gel_parsestack));
if G_UNLIKELY (!testparse)
gel_errorout (_("ERROR: Probably corrupt stack!"));
if(finished) *finished = FALSE;
if (finished != NULL)
*finished = FALSE;
return NULL;
}
/* local nodes should not exist now, they should all
have been eaten */
if (gel_get_local_node (gel_parsestack->data,
FALSE /* first_arg */,
NULL,
NULL)) {
gel_freetree (gel_stack_pop (&gel_parsestack));
gel_errorout (_("ERROR: 'local' in a wrong place, can only be first statement in a function!"));
if (finished != NULL)
*finished = TRUE;
return NULL;
}
gel_replace_equals (gel_parsestack->data, FALSE /* in_expression */);
......
......@@ -136,23 +136,37 @@ gel_compile_node(GelETree *t,GString *gs)
case GEL_FUNCTION_NODE:
g_assert(t->func.func->type==GEL_USER_FUNC);
/*g_assert(t->func.func->id==NULL);*/
g_string_append_printf (gs, ";%s;%s;%d;%d;%d;%d;%d;",
g_string_append_printf (gs,
";%s;%s;n%d;v%d;p%d;o%d;l%d;e%d;b%d",
t->func.func->id ? t->func.func->id->token : "*",
t->func.func->symbolic_id ? t->func.func->symbolic_id->token : "*",
t->func.func->nargs,
t->func.func->vararg,
t->func.func->propagate_mod,
t->func.func->no_mod_all_args,
t->func.func->local_all);
t->func.func->local_all,
t->func.func->never_on_subst_list,
t->func.func->built_subst_dict);
/* Make sure to also update calc compile_funcs_in_dict
* and related! */
if (t->func.func->local_idents == NULL)
g_string_append (gs, "-");
g_string_append (gs, ";-");
for (li = t->func.func->local_idents; li != NULL; li = li->next) {
GelToken *tok = li->data;
if (li != t->func.func->local_idents)
g_string_append_printf (gs, ",%s", tok->token);
else
g_string_append_printf (gs, "%s", tok->token);
g_string_append_printf (gs, ";%s", tok->token);
}
if (t->func.func->subst_dict == NULL)
g_string_append (gs, ";-");
for (li = t->func.func->subst_dict; li != NULL; li = li->next) {
GelToken *tok = li->data;
if (li != t->func.func->subst_dict)
g_string_append_printf (gs, ",%s", tok->token);
else
g_string_append_printf (gs, ";%s", tok->token);
}
for (li = t->func.func->named_args; li != NULL; li = li->next) {
GelToken *tok = li->data;
......@@ -206,6 +220,8 @@ gel_decompile_node(char **ptrptr)
int propagate_mod = -1;
int no_mod_all_args = -1;
int local_all = -1;
int never_on_subst_list = -1;
int built_subst_dict = -1;
int quote;
int oper;
int i,j;
......@@ -213,7 +229,7 @@ gel_decompile_node(char **ptrptr)
GelMatrixW *m;
GelETree *li = NULL;
GelETree *args;
GSList *oli, *local_idents;
GSList *oli, *local_idents, *subst_dict;
GelEFunc *func;
mpw_t tmp;
......@@ -351,29 +367,39 @@ gel_decompile_node(char **ptrptr)
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (!p) return NULL;
nargs = -1;
sscanf(p,"%d",&nargs);
sscanf(p,"n%d",&nargs);
if G_UNLIKELY (nargs==-1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (!p) return NULL;
sscanf(p,"%d",&vararg);
sscanf(p,"v%d",&vararg);
if G_UNLIKELY (vararg == -1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (!p) return NULL;
sscanf(p,"%d",&propagate_mod);
sscanf(p,"p%d",&propagate_mod);
if G_UNLIKELY (propagate_mod == -1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (!p) return NULL;
sscanf(p,"%d",&no_mod_all_args);
sscanf(p,"o%d",&no_mod_all_args);
if G_UNLIKELY (no_mod_all_args == -1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (p == NULL) return NULL;
sscanf(p,"%d",&local_all);
sscanf(p,"l%d",&local_all);
if G_UNLIKELY (local_all == -1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (p == NULL) return NULL;
sscanf(p,"e%d",&never_on_subst_list);
if G_UNLIKELY (never_on_subst_list == -1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (p == NULL) return NULL;
sscanf(p,"b%d",&built_subst_dict);
if G_UNLIKELY (built_subst_dict == -1) return NULL;
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (p == NULL) return NULL;
local_idents = NULL;
......@@ -386,6 +412,18 @@ gel_decompile_node(char **ptrptr)
g_strfreev (s);
}
p = strtok_r (NULL,";", ptrptr);
if G_UNLIKELY (p == NULL) return NULL;
subst_dict = NULL;
if (strcmp (p, "-") != 0) {
char **s;
s = g_strsplit (p, ",", -1);
for (i = 0; s[i] != NULL; i++) {
subst_dict = g_slist_append (subst_dict, d_intern (s[i]));
}
g_strfreev (s);
}
oli = NULL;
for(i=0;i<nargs;i++) {
p = strtok_r (NULL,";", ptrptr);
......@@ -412,7 +450,10 @@ gel_decompile_node(char **ptrptr)
func->propagate_mod = propagate_mod ? 1 : 0;
func->no_mod_all_args = no_mod_all_args ? 1 : 0;
func->local_all = local_all ? 1 : 0;
func->never_on_subst_list = never_on_subst_list ? 1 : 0;
func->built_subst_dict = built_subst_dict ? 1 : 0;
func->local_idents = local_idents;
func->subst_dict = subst_dict;
GEL_GET_NEW_NODE(n);
n->type = GEL_FUNCTION_NODE;
......
......@@ -185,6 +185,7 @@ d_copyfunc(GelEFunc *o)
}
n->named_args = g_slist_copy (o->named_args);
n->local_idents = g_slist_copy (o->local_idents);
n->subst_dict = g_slist_copy (o->subst_dict);
n->extra_dict = g_slist_copy (o->extra_dict);
for (li = n->extra_dict; li != NULL; li = li->next)
......@@ -206,6 +207,9 @@ d_makerealfunc(GelEFunc *o,GelToken *id, gboolean use)
n = g_slice_dup (GelEFunc, o);
/* never copy is_local! */
n->is_local = 0;
n->id = id;
if (o->symbolic_id == NULL)
n->symbolic_id = o->id;
......@@ -226,6 +230,7 @@ d_makerealfunc(GelEFunc *o,GelToken *id, gboolean use)
o->extra_dict = NULL;
o->named_args = NULL;
o->local_idents = NULL;
o->subst_dict = NULL;
o->nargs = 0;
} else {
GSList *li;
......@@ -234,6 +239,7 @@ d_makerealfunc(GelEFunc *o,GelToken *id, gboolean use)
li->data = d_copyfunc (li->data);
n->named_args = g_slist_copy (o->named_args);
n->local_idents = g_slist_copy (o->local_idents);
n->subst_dict = g_slist_copy (o->subst_dict);
}
if (n->on_subst_list) {
......@@ -268,24 +274,34 @@ d_setrealfunc(GelEFunc *n,GelEFunc *fake, gboolean use)
n->data.user = gel_copynode(fake->data.user);
}
n->never_on_subst_list = fake->never_on_subst_list;
n->vararg = fake->vararg;
n->propagate_mod = fake->propagate_mod;
n->no_mod_all_args = fake->no_mod_all_args;
n->local_all = fake->local_all;
/* Never copy is_local */
n->built_subst_dict = fake->built_subst_dict;
if(use) {
n->named_args = fake->named_args;
n->local_idents = fake->local_idents;
n->subst_dict = fake->subst_dict;
n->nargs = fake->nargs;
fake->named_args = NULL;
fake->local_idents = NULL;
fake->nargs = 0;
} else {
n->named_args = g_slist_copy (fake->named_args);
n->local_idents = g_slist_copy (fake->local_idents);
n->nargs = fake->nargs;
}
fake->subst_dict = NULL;
if (use) {
n->extra_dict = fake->extra_dict;
fake->extra_dict = NULL;
} else {
GSList *li;
n->named_args = g_slist_copy (fake->named_args);
n->local_idents = g_slist_copy (fake->local_idents);
n->subst_dict = g_slist_copy (fake->subst_dict);
n->nargs = fake->nargs;
n->extra_dict = g_slist_copy (fake->extra_dict);
for (li = n->extra_dict; li != NULL; li = li->next)
li->data = d_copyfunc (li->data);
......@@ -659,6 +675,7 @@ d_freefunc (GelEFunc *n)
g_slist_free (n->named_args);
g_slist_free (n->local_idents);
g_slist_free (n->subst_dict);
g_slice_free (GelEFunc, n);
}
......@@ -692,6 +709,7 @@ d_replacefunc(GelEFunc *old,GelEFunc *_new)
g_slist_free (old->named_args);
g_slist_free (old->local_idents);
g_slist_free (old->subst_dict);
for (li = old->extra_dict; li != NULL; li = li->next) {
d_freefunc (li->data);
......@@ -721,9 +739,18 @@ d_set_ref(GelEFunc *n,GelEFunc *ref)
n->type = GEL_REFERENCE_FUNC;
g_slist_free (n->named_args);
g_slist_free (n->local_idents);
g_slist_free (n->subst_dict);
n->nargs = 0;
n->named_args = NULL;
n->local_idents = NULL;
n->subst_dict = NULL;
n->never_on_subst_list = 0;
n->vararg = 0;
n->propagate_mod = 0;
n->no_mod_all_args = 0;
n->local_all = 0;
/* don't touch is_local */
n->built_subst_dict = 0;
n->data.ref = ref;
}
......@@ -740,10 +767,20 @@ d_set_value(GelEFunc *n,GelETree *value)
n->type = GEL_VARIABLE_FUNC;
g_slist_free (n->named_args);
g_slist_free (n->local_idents);
g_slist_free (n->subst_dict);
n->nargs = 0;
n->named_args = NULL;
n->local_idents = NULL;
n->subst_dict = NULL;
n->never_on_subst_list = 0;
n->vararg = 0;
n->propagate_mod = 0;
n->no_mod_all_args = 0;
n->local_all = 0;
/* don't touch is_local */
n->built_subst_dict = 0;
n->data.user = value;
}
......@@ -776,7 +813,8 @@ d_popcontext (void)
GelContextFrame *of;
if (context.top != 0) {
for (li = subst; li != NULL; li = li->next) {
li = subst;
while (li != NULL) {
GelEFunc *func = li->data;
if (context.top == 1)
func->on_subst_list = 0;
......@@ -799,9 +837,24 @@ d_popcontext (void)
if (func->context >= context.top)
func->context = context.top - 1;
/* If subst_dict goes to NULL, we no
* longer need to keep this around on
* the subst_lists */
if (func->subst_dict == NULL) {
if (substlast != NULL) {
substlast = g_slist_remove_link (substlast, li);
li = substlast->next;
} else {
subst = g_slist_remove_link (subst, subst);
li = subst;