Added symbol support on parser
This commit is contained in:
@@ -1 +1 @@
|
||||
5 10 20
|
||||
5 10 20 + print
|
||||
|
||||
60
toyforth.c
60
toyforth.c
@@ -63,8 +63,10 @@ tfobj *createObject(int type)
|
||||
tfobj *createStringObject(char *s, size_t len)
|
||||
{
|
||||
tfobj *obj = createObject(TFOBJ_TYPE_STR);
|
||||
obj->str.ptr = s;
|
||||
obj->str.ptr = xmalloc(len+1);
|
||||
obj->str.len = len;
|
||||
memcpy(obj->str.ptr, s, len);
|
||||
obj->str.ptr[len] = 0;
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -137,6 +139,23 @@ tfobj *parseNumber(tfparser *parser)
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Return true if the character 'c' is one of the characters
|
||||
* acceptable for our symbols.
|
||||
*/
|
||||
int isSymbolChar(int c)
|
||||
{
|
||||
char symchars[] = "+-*/%";
|
||||
return isalpha(c) || strchr(symchars, c) != NULL;
|
||||
}
|
||||
|
||||
tfobj *parseSymbol(tfparser *parser)
|
||||
{
|
||||
char *start = parser->p;
|
||||
while (parser->p[0] && isSymbolChar(parser->p[0])) parser->p++;
|
||||
int len = parser->p - start;
|
||||
return createSymbolObject(start, len);
|
||||
}
|
||||
|
||||
tfobj *compile(char *prg)
|
||||
{
|
||||
tfparser parser;
|
||||
@@ -152,8 +171,11 @@ tfobj *compile(char *prg)
|
||||
parseSpaces(&parser);
|
||||
if (parser.p[0] == 0) break; // End of program reached.
|
||||
|
||||
if (isdigit(parser.p[0]) || parser.p[0] == '-') {
|
||||
if (isdigit(parser.p[0]) ||
|
||||
(parser.p[0] == '-' && isdigit(parser.p[1]))) {
|
||||
obj = parseNumber(&parser);
|
||||
} else if (isSymbolChar(parser.p[0])) {
|
||||
obj = parseSymbol(&parser);
|
||||
} else {
|
||||
obj = NULL;
|
||||
}
|
||||
@@ -173,21 +195,27 @@ tfobj *compile(char *prg)
|
||||
|
||||
/* ############################ Execute the program ##################################### */
|
||||
|
||||
void exec(tfobj *obj) {
|
||||
// TODO: unimplmented function
|
||||
for (size_t j = 0; j < obj->list.len; j++) {
|
||||
tfobj *o = obj->list.ele[j];
|
||||
switch (o->type) {
|
||||
case TFOBJ_TYPE_INT:
|
||||
printf("%d", o->i);
|
||||
break;
|
||||
default:
|
||||
printf("?");
|
||||
break;
|
||||
void printObject(tfobj *obj) {
|
||||
switch (obj->type) {
|
||||
case TFOBJ_TYPE_INT:
|
||||
printf("%d", obj->i);
|
||||
break;
|
||||
case TFOBJ_TYPE_LIST:
|
||||
printf("[");
|
||||
for (size_t j = 0; j < obj->list.len; j++) {
|
||||
tfobj *o = obj->list.ele[j];
|
||||
printObject(o);
|
||||
printf(" ");
|
||||
}
|
||||
printf(" ");
|
||||
printf("]");
|
||||
break;
|
||||
case TFOBJ_TYPE_SYMBOL:
|
||||
printf("'%s", obj->str.ptr);
|
||||
break;
|
||||
default:
|
||||
printf("?");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* ############################### Main ################################################# */
|
||||
@@ -217,7 +245,7 @@ int main(int argc, char **argv)
|
||||
//printf("Program text: \"%s\"\n", prgtext);
|
||||
|
||||
tfobj *prg = compile(prgtext);
|
||||
exec(prg);
|
||||
printObject(prg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user