aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/src/calc.sl
diff options
context:
space:
mode:
Diffstat (limited to 'libslang/src/calc.sl')
-rw-r--r--libslang/src/calc.sl374
1 files changed, 374 insertions, 0 deletions
diff --git a/libslang/src/calc.sl b/libslang/src/calc.sl
new file mode 100644
index 0000000..813dccf
--- /dev/null
+++ b/libslang/src/calc.sl
@@ -0,0 +1,374 @@
+variable X = Any_Type[1];
+X[0] = "foo";
+
+% a print function
+_debug_info = 1;
+set_float_format ("%.32e");
+define p(obj)
+{
+ () = fprintf (stdout, "%S\n", obj);
+ () = fflush (stdout);
+}
+
+define print_struct (s)
+{
+ variable name, value;
+
+ foreach (get_struct_field_names (s))
+ {
+ name = ();
+ value = get_struct_field (s, name);
+
+ () = printf ("s.%s = %S\n", name, value);
+ }
+}
+
+static variable Static_Variable;
+
+static define test1 ()
+{
+ loop (_NARGS) p;
+}
+
+define test ()
+{
+ usage ("silly silly silly");
+ variable args = __pop_args (_NARGS);
+ test1 (__push_args (args));
+}
+
+define calc_take_input_hook ()
+{
+ while (_stkdepth ())
+ p ();
+}
+
+define print_array (a)
+{
+ variable num_dims, dims;
+ variable nr, nc;
+ variable i, j;
+
+ (dims ,num_dims,) = array_info (a);
+ if (num_dims > 2)
+ {
+ p (a);
+ return;
+ }
+
+ nr = dims [0];
+ nc = 0;
+ if (num_dims == 2)
+ nc = dims[1];
+
+ _for (0, nr - 1, 1)
+ {
+ i = ();
+ !if (nc)
+ {
+ () = printf ("Array[%d] = %S\n", i, a[i]);
+ continue;
+ }
+ _for (0, nc - 1, 1)
+ {
+ j = ();
+ () = printf ("\t%S", a[i, j]);
+ }
+ () = fputs ("\n", stdout);
+ }
+}
+
+define read_file (file)
+{
+ variable line, len;
+ variable root, tail, s;
+ variable fp;
+
+ fp = fopen (file, "r");
+ if (fp == NULL)
+ error ("unable to open file");
+
+ root = NULL;
+ tail = NULL;
+ while (-1 != fgets (&line, fp))
+ {
+ s = struct { next, value };
+ s.value = line;
+ s.next = NULL;
+
+ if (root == NULL)
+ root = s;
+ else
+ tail.next = s;
+
+ tail = s;
+ }
+ () = fclose (fp);
+ return root;
+}
+
+define list_len (list)
+{
+ variable len = 0;
+
+ foreach (list) using ("next")
+ {
+ () = ();
+ len++;
+ }
+ return len;
+}
+
+
+
+
+
+
+% calc.sl--- Init file for calc. This file must be placed in the default
+% directory for calc and is automatically loaded when calc runs.
+%
+% This file contains S-Lang code for Newton's method, etc...
+%
+% Here is a function which computes the root of the equation y = f(x) using
+% Newtons method. The usage is:
+%
+% root = newton(s, &f);
+%
+% where s is a seed value and f is the function whose root is sought.
+%
+% For example, consider the function my_fun(x) = x^2 - 2 with solution
+% x = sqrt(2). This function may be expressed in S-Lang as:
+%
+% define my_func(x)
+% {
+% return (x * x - 2);
+% }
+%
+% To solve the equation my_fun(x) = 0 using the newton routine below, use
+%
+% newton(5.0, &myfun);
+%
+% Here, I have randomly chosen 5.0 as an initial guess. In addition,
+% I have used the '&' operator to pass the function 'myfun' to the routine.
+
+
+% Newton's method requires the derivative of a function. Here is such a
+% function called by newton. Given f(x), it returns df/dx at the point x.
+%
+% Its usage is:
+%
+% derivative(x, &f);
+
+define derivative(x, f)
+{
+ variable dx;
+ dx = 1.0e-4; % small number
+
+ return ((@f(x + dx) - @f(x - dx))/(2 * dx));
+}
+
+% And now the Newton's method:
+
+define newton(x, f)
+{
+ variable err, max, dx;
+
+ err = 1.0e-6;
+ max = 1000;
+
+ while (max)
+ {
+ --max;
+ dx = @f(x) / derivative(x, f);
+ if (abs(dx) < err)
+ {
+ return(x);
+ }
+
+ x -= dx;
+ }
+
+ message ("\7Root not found. Try another seed!");
+ return(x);
+}
+
+
+
+%% This is a standard benchmark for interpreters. It is a heavily
+%% recursive routine that returns the nth Fibonacci number.
+%% It is defined recursively as:
+%%
+%% f_0 = 0, f_1 = 1, .... , f_{n+1} = f_n + f_{n-1}, ...
+%%
+%% or {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...}
+%%
+
+define fib(); % required for recursion
+
+define fib(n)
+{
+ !if (n) return(0);
+ --n;
+ !if (n) return(1);
+
+ return fib(n) + fib(n--, n); %Note that this expression parses to RPN
+ % n fib --n n fib +
+ %and since --n does not change the stack, the
+ %effect is the same as the C comma operator.
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Two routines which illustrate the how to deal with files
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% type out a file to terminal
+define type_file(file)
+{
+ variable fp, n, line;
+
+ fp = fopen(file, "r");
+ if (fp == NULL)
+ verror ("%s failed to open.", file);
+
+ while (-1 != fgets (&line, fp))
+ {
+ () = fputs (line, stdout);
+ }
+
+ if (-1 == fclose(fp))
+ verror ("Error closing %s", file);
+}
+
+
+%
+% Here is a function that prints the number of lines in a file
+%
+
+define count_lines1 (file)
+{
+ variable fp, lines, nchars, num_lines, st;
+
+ fp = fopen (file, "r");
+ if (fp == NULL)
+ verror ("count_lines1: unable to open %s", file);
+
+ st = stat_file (file);
+ if (st == NULL)
+ verror ("stat_file failed");
+
+ lines = fgetslines (fp);
+ nchars = st.st_size;
+
+ num_lines = length (lines);
+
+ () = fclose (fp);
+ vmessage ("%s consists of %d characters and %d lines.\n",
+ file, nchars, num_lines);
+}
+
+
+define count_lines(f)
+{
+ variable fp, n, nchars, dn, line;
+
+ fp = fopen(f, "r");
+ if (fp == NULL) error("Unable to open file!");
+ n = 0; nchars = 0;
+
+ while (dn = fgets (&line, fp), dn != -1)
+ {
+ ++n;
+ nchars += dn;
+ }
+ () = fclose(fp); %/* ignore return value */
+
+ vmessage ("%s consists of %d characters and %d lines.\n",
+ f, nchars, n);
+}
+
+define count_lines2(f)
+{
+ variable fp, n, nchars, dn, line;
+
+ fp = fopen(f, "r");
+ if (fp == NULL) error("Unable to open file!");
+ n = 0; nchars = 0;
+
+ foreach (fp)
+ {
+ nchars += strlen ();
+ ++n;
+ }
+ () = fclose(fp); %/* ignore return value */
+
+ vmessage ("%s consists of %d characters and %d lines.\n",
+ f, nchars, n);
+}
+
+
+define count_lines3(f)
+{
+ variable fp, n, nchars, dn, line;
+
+ fp = fopen(f, "r");
+ if (fp == NULL) error("Unable to open file!");
+ n = 0; nchars = 0;
+
+ n = 1;
+ foreach (fp) using ("char")
+ {
+ variable ch = ();
+ if (ch == '\n')
+ n++;
+ nchars++;
+ }
+ () = fclose(fp); %/* ignore return value */
+
+ vmessage ("%s consists of %d characters and %d lines.\n",
+ f, nchars, n);
+}
+
+
+% an apropos function
+define apropos (what)
+{
+ variable n = _apropos(what, 0xF);
+ variable i, f1, f2, f3;
+
+ if (n) () = printf ("Found %d matches:\n", n);
+ else
+ {
+ () = printf ("No matches.\n");
+ return;
+ }
+
+ loop (n / 3)
+ {
+ f1 = (); f2 = (); f3 = ();
+ () = printf ("%-26s %-26s %s\n", f1, f2, f3);
+ }
+ n = n mod 3;
+ loop (n)
+ {
+ f1 = ();
+ () = printf ("%-26s ", f1);
+ }
+ if (n) () = printf("\n");
+}
+
+%%% more help (called from calc.c)
+define calc_help ()
+{
+ p("Additional functions:");
+ p(" p(); -- displays top element of the stack (discarding it).");
+ p(" quit(); -- quit calculator");
+ p(" apropos(\"STRING\"); -- lists all objects containing \"STRING\"");
+ p("\nExample: p (2.4 * E); yields 6.52388.\n");
+}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% end of calc.sl
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%