1
0
Fork 0

func "arcane/parse"

This commit is contained in:
Alex Kotov 2023-05-06 20:35:04 +04:00
parent a46827abc5
commit cee72a9c82
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
3 changed files with 81 additions and 0 deletions

View File

@ -2,6 +2,7 @@
#include "lexer.h"
#include "object.h"
#include "parser.h"
#include "tokens.h"
#include <assert.h>
@ -11,6 +12,7 @@
#include <string.h>
// Arcane Scheme Lisp internals
static struct Object *func_arcane_SLASH_parse(size_t args_count, struct Object **args_array);
static struct Object *func_arcane_SLASH_tokenize(size_t args_count, struct Object **args_array);
static struct Object *func_arcane_SLASH_typeof(size_t args_count, struct Object **args_array);
// Basic data structures
@ -44,6 +46,7 @@ static struct Object *func_newline(size_t args_count, struct Object **args_array
static struct Object builtins[] = {
// Arcane Scheme Lisp internals
{ .type = TYPE_PROCEDURE, .procedure = { "arcane/parse", func_arcane_SLASH_parse } },
{ .type = TYPE_PROCEDURE, .procedure = { "arcane/tokenize", func_arcane_SLASH_tokenize } },
{ .type = TYPE_PROCEDURE, .procedure = { "arcane/typeof", func_arcane_SLASH_typeof } },
// Basic data structures
@ -93,6 +96,68 @@ struct Object *builtins_get(const char *name)
* Arcane Scheme Lisp internals *
********************************/
struct Object *func_arcane_SLASH_parse(
size_t args_count,
struct Object **args_array
) {
assert(args_count == 1);
assert(args_array);
struct Object *tokens_obj = args_array[0];
assert(OBJECT_IS_LIST_HEAD(tokens_obj));
const Tokens tokens = Tokens_new();
assert(tokens);
while (!OBJECT_IS_NULL(tokens_obj)) {
assert(Object_is_pair(tokens_obj));
struct Object *const token_obj = tokens_obj->pair.car;
assert(Object_is_pair(token_obj));
struct Object *const type_obj = token_obj->pair.car;
assert(Object_is_symbol(type_obj));
struct Object *const val_obj = token_obj->pair.cdr;
assert(Object_is_string(val_obj));
enum TokenType token_type;
if (strcmp(type_obj->s, "TOKEN_ROUND_OPEN") == 0) {
token_type = TOKEN_ROUND_OPEN;
} else if (strcmp(type_obj->s, "TOKEN_ROUND_CLOSE") == 0) {
token_type = TOKEN_ROUND_CLOSE;
} else if (strcmp(type_obj->s, "TOKEN_SQUARE_OPEN") == 0) {
token_type = TOKEN_SQUARE_OPEN;
} else if (strcmp(type_obj->s, "TOKEN_SQUARE_CLOSE") == 0) {
token_type = TOKEN_SQUARE_CLOSE;
} else if (strcmp(type_obj->s, "TOKEN_CURLY_OPEN") == 0) {
token_type = TOKEN_CURLY_OPEN;
} else if (strcmp(type_obj->s, "TOKEN_CURLY_CLOSE") == 0) {
token_type = TOKEN_CURLY_CLOSE;
} else if (strcmp(type_obj->s, "TOKEN_QUOTE") == 0) {
token_type = TOKEN_QUOTE;
} else if (strcmp(type_obj->s, "TOKEN_TAG") == 0) {
token_type = TOKEN_TAG;
} else if (strcmp(type_obj->s, "TOKEN_IDENT") == 0) {
token_type = TOKEN_IDENT;
} else if (strcmp(type_obj->s, "TOKEN_NUM") == 0) {
token_type = TOKEN_NUM;
} else if (strcmp(type_obj->s, "TOKEN_STRING") == 0) {
token_type = TOKEN_STRING;
} else {
assert(0);
}
Tokens_append(tokens, token_type, val_obj->s);
tokens_obj = tokens_obj->pair.cdr;
}
struct Object *const program = parse(tokens);
Tokens_delete(tokens);
return program;
}
struct Object *func_arcane_SLASH_tokenize(
const size_t args_count,
struct Object **const args_array

View File

@ -36,6 +36,19 @@
(newline)
(displayln "=== GROUP: Arcane Scheme Lisp internals ========================")
(newline)
(displayln "--- TEST: arcane/parse -----------------------------------------")
(displayln
(arcane/parse
(list
(cons 'TOKEN_ROUND_OPEN "(")
(cons 'TOKEN_IDENT "displayln")
(cons 'TOKEN_ROUND_OPEN "(")
(cons 'TOKEN_IDENT "+")
(cons 'TOKEN_NUM "123")
(cons 'TOKEN_NUM "456")
(cons 'TOKEN_ROUND_CLOSE ")")
(cons 'TOKEN_ROUND_CLOSE ")"))))
(newline)
(displayln "--- TEST: arcane/tokenize --------------------------------------")
(displayln (arcane/tokenize "("))
(displayln (arcane/tokenize "#false"))

View File

@ -33,6 +33,9 @@ foo
"=== GROUP: Arcane Scheme Lisp internals ========================"
"--- TEST: arcane/parse -----------------------------------------"
(displayln (+ 123 456))
"--- TEST: arcane/tokenize --------------------------------------"
((TOKEN_ROUND_OPEN . "("))
((TOKEN_TAG . "false"))