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