#include "eval.h"

void main()
{
    value expr, nexpr;
    char str[100], *d;
    int flags;
    context new;
    var_list vl;
    struct Node *scan;

    init_context(&new);
    set_context(&new);

    if (!init_expr()) printf("init failed !\n");
    else {
	printf("expression ? "); scanf("%s", str);
	expr = compile(str);
	if (expr)
	{
	    /* Read variable values */
	    init_var_list(&vl);
	    make_var_list(expr, &vl); /* Should check for error return */
	    for (scan = vl.lh_Head; scan->ln_Succ; scan = scan->ln_Succ)
	    {
		printf("%s = ", scan->ln_Name);
		scanf("%s", str);
		if (str[0] != '!') /* no value */
		{
		    value val;

		    val = compile(str);
		    if (val) set_var_name(scan->ln_Name, val);
		    else printf("error = %d\n", eval_error);
		}
	    }

	    d = decompile(expr, str, 100);
	    if (d) printf("Expr is %s\n", d);
	    else printf("Decomp error\n");

	    /* Evaluate expression */
	    printf("flags ? ");scanf("%d", &flags);
	    nexpr = eval(expr, flags);
	    if (nexpr)
	    {
		d = decompile(nexpr, str, 100);
		if (d) printf("Eval is %s\n", d);
		else printf("Decomp error\n");
		free_expr(nexpr);
	    }
	    else printf("error = %d\n", eval_error);

	    /* Free variables */
	    for (scan = vl.lh_Head; scan->ln_Succ; scan = scan->ln_Succ)
	    {
		value val;

		if (val = get_var_name(scan->ln_Name))
		{
		    free_expr(val);
		    free_var_name(scan->ln_Name);
		}
		else printf("Variable %s had no value\n", scan->ln_Name);
	    }
	    free_var_list(&vl);

	    /* Test differentiation */
	    nexpr = differentiate(expr, "x");
	    if (nexpr)
	    {
		d = decompile(nexpr, str, 100);
		if (d) printf("Diff is %s\n", d);
		else printf("Decomp error\n");
		free_expr(nexpr);
	    }
	    else printf("diff error = %d\n", eval_error);

	    free_expr(expr);
	}
	else printf("Error = %d\n", eval_error);
    }
    cleanup_expr();
}

