]> code.bitgloo.com Git - clyne/interpreter.git/commitdiff
var define/expansion
authorClyne Sullivan <tullivan99@gmail.com>
Tue, 23 Jan 2018 17:00:30 +0000 (12:00 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Tue, 23 Jan 2018 17:00:30 +0000 (12:00 -0500)
README.md
parser.c
shell.c

index 385650c856e48b82f1d1ca606986d148dcbf3ba8..f2dbcabd8f9d055d2fddc65f4167c9279e1a4a53 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,6 +1,11 @@
 # interpreter
 This project aims to provide a very minimal scripting language for embedded systems. Many other languages already exist, such as Lua, Tcl, or BASIC; however, most implementations require certain system calls like a read() and write(), expecting a filesystem. This interpreter aims to be as independent as possible: parsing script from strings at a time, having minimal built-in functions (so the user can define their own prints and such), and only requiring a few library functions.  
   
-To use this program with your own device, only two functions are truly needed: malloc, and strcmp.  
+To use this program with your own device, only one function is truly neede: malloc, and calloc (though may switch to only malloc).  
   
-This project is still in heavy development, so don't expect much. Right now only function calls are supported, without variable name expansion. To include it in your own project, just link in parser.o and use the header files.
+Current features:  
+* function/variable defining in c
+* variable definition
+* function calling with variable expansion  
+  
+This project is still in heavy development, so don't expect much. To include it in your own project, just link in parser.o and use the header files.
index ba1ce2aee55ec0132664ebeb16401036e9fbc170..5e94e79d5e71bf0002c271cf02980af6bb61f604 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -1,11 +1,24 @@
 #include <parser.h>
 
 #include <stdbool.h>
-#include <string.h>
 #include <stdlib.h>
 
 static const char *interpreter_operators = "=(";
 
+bool strcmp(const char *a, const char *b)
+{
+       int i = 0;
+       for (; a[i] == b[i] && a[i] != '\0'; i++);
+       return a[i] == b[i];
+}
+
+bool strncmp(const char *a, const char *b, int count)
+{
+       int i = 0;
+       for (; a[i] == b[i] && i < count; i++);
+       return i == count;
+}
+
 uint8_t isalpha(char c)
 {
        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
@@ -81,7 +94,7 @@ bool namencmp(const char *name, const char *s)
 {
        uint16_t i;
        for (i = 0; name[i] == s[i] && s[i] != '\0'; i++);
-       return (name[i] == '\0');
+       return (name[i] == '\0' && !isname(s[i]));
 }
 
 uint16_t spacecount(const char *s)
@@ -91,10 +104,10 @@ uint16_t spacecount(const char *s)
        return i;
 }
 
-char *copystr(const char *s)
+char *copystr(const char *s, char end)
 {
        uint16_t len = 0;
-       while (s[len++] != '\n');
+       while (s[len++] != end);
        char *buf = (char *)malloc(len);
        for (uint16_t i = 0; i < len; i++)
                buf[i] = s[i];
@@ -109,31 +122,37 @@ char *copysubstr(const char *s, int end)
        return buf;
 }
 
+variable *interpreter_getvar(interpreter *interp, const char *line)
+{
+       for (uint16_t i = 0; i < interp->vcount; i++) {
+               if (namencmp(interp->names[i], line))
+                       return &interp->vars[i];
+       }
+
+       return 0;
+}
+
 int interpreter_doline(interpreter *interp, const char *line)
 {
        variable *bits[16];
        uint16_t offset = 0, boffset = 0;
 
        // check for var/func set or usage
+       int end;
 getvar:
-       for (uint16_t i = 0; i < interp->vcount; i++) {
-               if (namencmp(interp->names[i], line)) {
-                       bits[boffset++] = &interp->vars[i];
-                       // get past name
-                       for (uint16_t j = 0; interp->names[i][j] != '\0'; j++, offset++);
-                       break;
-               }
-       }
+       for (end = 0; isname(line[end]); end++);
+       variable *var = interpreter_getvar(interp, line);
 
-       // defining new variable
-       if (boffset == 0) {
-               uint16_t end;
-               for (end = 0; isname(line[end]); end++);
+       if (var != 0) {
+               bits[boffset++] = var;
+       } else {
+               // defining new variable
                interpreter_define_value(interp, copysubstr(line, end), 0);
                goto getvar; // try again
        }
 
-       // skip whitespace
+       // skip whitespace/name
+       offset += end;
        offset += spacecount(line + offset); 
 
        if (boffset == 0 && line[offset] != '=')
@@ -144,12 +163,10 @@ getvar:
                // print value
                return -99;
        } else if (line[offset] == '=') {
-               return -23;
                // assignment/expression
-               //offset++;
-               //offset += spacecount(line + offset);
-               //if (boffset > 0)
-               //      bits[boffset]->value = (uint32_t)copystr(line + offset);
+               offset++;
+               offset += spacecount(line + offset);
+               bits[0]->value = (uint32_t)copystr(line + offset, '\0');
        } else if (line[offset] == '(') {
                // function call
                offset++;
@@ -190,9 +207,12 @@ getvar:
                        for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' &&
                                        line[j] != ',' && line[j] != ')'; j++);
                        j -= offsets[i];
-                       interp->stack[i] = (char *)malloc(j);
-                       for (uint16_t k = 0; k < j; k++)
-                               ((char *)interp->stack[i])[k] = line[offsets[i] + k];
+
+                       variable *var = interpreter_getvar(interp, line + offsets[i]);
+                       if (var != 0)
+                               interp->stack[i] = copystr((char *)var->value, '\0');
+                       else
+                               interp->stack[i] = copysubstr(line + offsets[i], j);
                }
 
                ((func_t)bits[0]->value)(interp->stack);
diff --git a/shell.c b/shell.c
index b4bfd63886a17b573a0486a4b25d9d39c1e0ffd1..b19add8b9d3b6cf90605e95f3372f48fc3a6be85 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -12,11 +12,15 @@ int main(int argc, char *argv[])
        interpreter interp;
 
        interpreter_init(&interp);
-       interpreter_define_value(&interp, "answer", 42);
+       interpreter_define_value(&interp, "answer", "42");
        interpreter_define_cfunc(&interp, "test", test);
 
-       if (argc == 2) {
-               printf("%d\n", interpreter_doline(&interp, argv[1]));
+       if (argc > 1) {
+               for (int i = 1; i < argc; i++) {
+                       int result = interpreter_doline(&interp, argv[i]);
+                       if (result != 0)
+                               printf("%d\n", result);
+               }
        }
 
        return 0;