var define/expansion

master
Clyne Sullivan 7 years ago
parent 548804f4b4
commit accef5f54c

@ -1,6 +1,11 @@
# interpreter # 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. 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.

@ -1,11 +1,24 @@
#include <parser.h> #include <parser.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
static const char *interpreter_operators = "=("; 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) uint8_t isalpha(char c)
{ {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
@ -81,7 +94,7 @@ bool namencmp(const char *name, const char *s)
{ {
uint16_t i; uint16_t i;
for (i = 0; name[i] == s[i] && s[i] != '\0'; 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) uint16_t spacecount(const char *s)
@ -91,10 +104,10 @@ uint16_t spacecount(const char *s)
return i; return i;
} }
char *copystr(const char *s) char *copystr(const char *s, char end)
{ {
uint16_t len = 0; uint16_t len = 0;
while (s[len++] != '\n'); while (s[len++] != end);
char *buf = (char *)malloc(len); char *buf = (char *)malloc(len);
for (uint16_t i = 0; i < len; i++) for (uint16_t i = 0; i < len; i++)
buf[i] = s[i]; buf[i] = s[i];
@ -109,31 +122,37 @@ char *copysubstr(const char *s, int end)
return buf; 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) int interpreter_doline(interpreter *interp, const char *line)
{ {
variable *bits[16]; variable *bits[16];
uint16_t offset = 0, boffset = 0; uint16_t offset = 0, boffset = 0;
// check for var/func set or usage // check for var/func set or usage
int end;
getvar: getvar:
for (uint16_t i = 0; i < interp->vcount; i++) { for (end = 0; isname(line[end]); end++);
if (namencmp(interp->names[i], line)) { variable *var = interpreter_getvar(interp, line);
bits[boffset++] = &interp->vars[i];
// get past name
for (uint16_t j = 0; interp->names[i][j] != '\0'; j++, offset++);
break;
}
}
if (var != 0) {
bits[boffset++] = var;
} else {
// defining new variable // defining new variable
if (boffset == 0) {
uint16_t end;
for (end = 0; isname(line[end]); end++);
interpreter_define_value(interp, copysubstr(line, end), 0); interpreter_define_value(interp, copysubstr(line, end), 0);
goto getvar; // try again goto getvar; // try again
} }
// skip whitespace // skip whitespace/name
offset += end;
offset += spacecount(line + offset); offset += spacecount(line + offset);
if (boffset == 0 && line[offset] != '=') if (boffset == 0 && line[offset] != '=')
@ -144,12 +163,10 @@ getvar:
// print value // print value
return -99; return -99;
} else if (line[offset] == '=') { } else if (line[offset] == '=') {
return -23;
// assignment/expression // assignment/expression
//offset++; offset++;
//offset += spacecount(line + offset); offset += spacecount(line + offset);
//if (boffset > 0) bits[0]->value = (uint32_t)copystr(line + offset, '\0');
// bits[boffset]->value = (uint32_t)copystr(line + offset);
} else if (line[offset] == '(') { } else if (line[offset] == '(') {
// function call // function call
offset++; offset++;
@ -190,9 +207,12 @@ getvar:
for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' && for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' &&
line[j] != ',' && line[j] != ')'; j++); line[j] != ',' && line[j] != ')'; j++);
j -= offsets[i]; j -= offsets[i];
interp->stack[i] = (char *)malloc(j);
for (uint16_t k = 0; k < j; k++) variable *var = interpreter_getvar(interp, line + offsets[i]);
((char *)interp->stack[i])[k] = line[offsets[i] + k]; 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); ((func_t)bits[0]->value)(interp->stack);

@ -12,11 +12,15 @@ int main(int argc, char *argv[])
interpreter interp; interpreter interp;
interpreter_init(&interp); interpreter_init(&interp);
interpreter_define_value(&interp, "answer", 42); interpreter_define_value(&interp, "answer", "42");
interpreter_define_cfunc(&interp, "test", test); interpreter_define_cfunc(&interp, "test", test);
if (argc == 2) { if (argc > 1) {
printf("%d\n", interpreter_doline(&interp, argv[1])); for (int i = 1; i < argc; i++) {
int result = interpreter_doline(&interp, argv[i]);
if (result != 0)
printf("%d\n", result);
}
} }
return 0; return 0;

Loading…
Cancel
Save