---------- Forwarded message ---------
From: Brian Tiffin <btif...@users.sf.net>
Date: Sun, Aug 28, 2016, 5:15 AM
Subject: [unicon:discussion] S-Lang interpreter embedded in Unicon
To: [unicon:discussion] <contributi...@discussion.unicon.p.re.sf.net>


Take 2:

I have a few questions for Jafar and Clinton, *or other insiders*.

New slang.c

/* Embed an S-Lang interpreter in a Unicon loadfunc extension
tectonics: gcc -o slang.so -shared -fpic slang.c -lslang

*/
#include <stdio.h>#include <slang.h>#include "icall.h"

/* Init S-Lang if necessary, and then evaluate a string argv[1] Usage
from Unicon     slang = loadfunc("./slang.so", "slang")     x :=
slang("S-Lang statements;") The last result stacked by S-Lang is
returned to Unicon Integer, Double, String and Array as numeric List
values allowed*/int slang(int argc, descriptor *argv) {
    static int slang_loaded = 0;

    int tos;
    int i, iv;
    double r;
    char *s, *slast = NULL;
    /* Limit to single dimension arrays for this version */
    word list;
    SLang_Array_Type *at;
    SLindex_Type ind;


    /* load slang, and all intrinsics */

    if (!slang_loaded) {

        if (-1 == SLang_init_all()) {
            /* Program malfunction */

#ifdef DEBUG

            fprintf(stderr, "Can't initialize S-Lang\n");

#endif
            Error(500);
        } else {
            slang_loaded = 1;

        }
    }

    /* ensure argv[1] is a string */
    ArgString(1)

    /* evaluate argv[1] */
    if (-1 == SLang_load_string(StringVal(argv[1]))) {
        /* Reset S-Lang to allow later code attempts */
        SLang_restart(1);
        SLang_set_error(0);


        /* report invalid procedure type error to Unicon */
        Error(178);
    }

    tos = SLang_peek_at_stack();
    switch (tos) {
        case SLANG_INT_TYPE:

            /* return an integer to Unicon */

            SLang_pop_integer(&i);
            RetInteger(i);
            break;
        case SLANG_DOUBLE_TYPE:
            /* return a real to Unicon */
            SLang_pop_double(&r);
            RetReal(r);
            break;
        case SLANG_STRING_TYPE:
            /* return an allocated string to Unicon */
            /* memory allocation strategy; last string is freed */
            if (slast)  SLfree(slast);
            SLpop_string(&s);
            slast = s;
            RetString(s);
            break;
        case SLANG_ARRAY_TYPE:
            /* return an array as a Unicon list */
            if (-1 == SLang_pop_array_of_type(&at, SLANG_DOUBLE_TYPE)) {
                /* report malfuntion */
                Error(500);
            }
            if (at->num_dims != 1) {
                /* report invalid value */
                Error(205);
            }
            double *doubles = malloc(sizeof(double) * at->num_elements);
            for (i = 0; i < at->num_elements; i++) {
                (void) SLang_get_array_element(at, &i, &r);
                doubles[i] = r;
            }
            /*             mkRlist was defined as (int [], n) now
(double [], n)            */
            list = mkRlist(doubles, at->num_elements);

            /* *** unsure who owns the doubles input array *** */
            free(doubles);
            RetList(list);
            break;
        default:#ifdef DEBUG
            fprintf(stderr, "Invalid S-Lang datatype %d\n", tos);#endif
            /* report invalid value error to Unicon */
            Error(205);
    }}

And some more test head, slang.icn

## slang.icn, load a S-Lang interpreter, and evaluate some
statements## tectonics: gcc -o slang.so -shared -fpic slang.c
-lslang## Date: August 2016

# Modified: 2016-08-28/05:49-0400#link ximageprocedure main()
    # embed the interpreter
    slang := loadfunc("./slang.so", "slang")

    # return a computed variable, sum of list

    code := "variable slsum = sum([0,1,2,3,4,5,6,7,8,9]);_             slsum;"

    result := slang(code)

    write("Unicon sum: ", result)


    # return value is from S-Lang printf (bytes written)
    code := "printf(\"S-Lang: %f\\n\", slsum);"
    write("Unicon printf length: ", slang(code))

    # S-Lang IO mix in
    code := "printf(\"S-Lang: %s = %f and %s = %f\\n\",_

           \"hypot([3,4])\", hypot([3,4]),_
\"sumsq([3,4])\", sumsq([3,4]));"

    write("Unicon printf length: ", slang(code))

    # 3D vector length

    code := "variable A = [3,4,5]; hypot(A);"

    write("Unicon hypot([3,4,5]): ", slang(code))

    # try some strings, last one created will stay allocated
    code := "\"abc\";"
    write("Unicon abc: ", slang(code))
    code := "\"def\";"
    write("Unicon def: ", slang(code))

    # Pass an array, retured as a list of Real
    code := "[1,2.2,3];"
    L := slang(code)
    writes("Unicon [1,2.2,3]: ")
    every i := !L do writes(i, " ")
    write()

    # Cummulative summation
    code := "cumsum([1.1, 2.2, 3.3, 4.4]);"
    L := slang(code)
    writes("Unicon from ", code, ": ")
    every i := !L do writes(i, " ")
    write()

    # try a small S-Lang program
    code := "variable t, i; t = 0; for (i = 0; i < 10; i++) t += i; t;"
    write("Unicon from ", code, ": ", slang(code))

    # convert an error to failure
    write()
    &error := 1
    code := "[1, 2, \"abc\"];"
    write("Unicon trying: ", code)
    slang(code)
    write("Unicon S-Lang &errornumber: ", &errornumber)
    write()

    # and an abend
    code := "1/0"
    slang(code)end

And the flying carpet pass

[~/wip/writing/unicon/programs]05:53$ unicon -quiet -s -v0 slang.icn -x
Unicon sum: 45.0
S-Lang: 45.000000
Unicon printf length: 18
S-Lang: hypot([3,4]) = 5.000000 and sumsq([3,4]) = 25.000000
Unicon printf length: 61
Unicon hypot([3,4,5]): 7.071067811865476
Unicon abc: abc
Unicon def: def
Unicon [1,2.2,3]: 1.0 2.2 3.0
Unicon from cumsum([1.1, 2.2, 3.3, 4.4]);: 1.1 3.3 6.6 11.0
Unicon from variable t, i; t = 0; for (i = 0; i < 10; i++) t += i; t;: 45

Unicon trying: [1, 2, "abc"];
Unable to typecast Integer_Type to String_Type
***string***:1:<top-level>:Type Mismatch
Unicon S-Lang &errornumber: 178

Divide by Zero
***string***:1:<top-level>:Divide by Zero

Run-time error 178
File slang.icn; Line 70

Traceback:
   main()
   slang("1/0") from line 70 in slang.icn

And now the pesky new guy questions.

There is a bug, I think, in icall.h, it has mkRlist prototyped as (int x[],
int n). I changed my local copy to (double x[], int n).

When icall.h, Error(n) is called, is that supposed to set &errortext or are
there other steps involved?

Who owns the mkIlist, mkRlist input *x* C arrays? Are they to be freed
after the call to mkRlist() before the RetList? Same kind of question about
RetString. If a C routine mallocs that data space, what are the proper
steps to ensure the block is safely freed?

And to everybody:

Why hasn't someone wrapped unicon in a loadfunc to emulate (rather slowly
mind you, but it feels like it should work nicely) a *limited* eval of
Unicon code from inside Unicon? :-)

Have good, make well,
Brian

Attachments:

   - icall.h
   
<https://sourceforge.net/p/unicon/discussion/contributions/thread/3f579d7b/c494/attachment/icall.h>
   (14.4 kB; text/x-chdr)
   - slang.c
   
<https://sourceforge.net/p/unicon/discussion/contributions/thread/3f579d7b/c494/attachment/slang.c>
   (3.1 kB; text/x-csrc)
   - slang.icn
   
<https://sourceforge.net/p/unicon/discussion/contributions/thread/3f579d7b/c494/attachment/slang.icn>
   (2.0 kB; application/octet-stream)

------------------------------

S-Lang interpreter embedded in Unicon
<https://sourceforge.net/p/unicon/discussion/contributions/thread/3f579d7b/?limit=25#c494>
------------------------------

Sent from sourceforge.net because you indicated interest in
https://sourceforge.net/p/unicon/discussion/contributions/

To unsubscribe from further messages, please visit
https://sourceforge.net/auth/subscriptions/
-- 

-- Sent From My Smartphone
------------------------------------------------------------------------------
_______________________________________________
Unicon-group mailing list
Unicon-group@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/unicon-group

Reply via email to