refactor: spread across files

This commit is contained in:
2026-07-21 11:53:10 +02:00
parent a324252e8c
commit fb40d83244
5 changed files with 173 additions and 142 deletions
+22
View File
@@ -0,0 +1,22 @@
#include "lisp.h"
Node *lisp_function_addition(Nodes *args) {
if (args->count != 2) {
printf("'+' expects two arguments!\n");
return NULL;
}
if (args->items[0].kind != NODE_KIND_NUMBER ||
args->items[1].kind != NODE_KIND_NUMBER) {
printf("'+' can only add numbers, you specified something else!\n");
return NULL;
}
Node *node = malloc(sizeof(Node));
node->kind = NODE_KIND_NUMBER;
intptr_t a = args->items[0].as_number;
intptr_t b = args->items[1].as_number;
node->as_number = a + b;
return node;
}
+33 -142
View File
@@ -1,90 +1,10 @@
#include <ctype.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOB_IMPLEMENTATION
#include "nob.h"
typedef enum e_TokenKind {
TOKEN_KIND_PAR_LEFT,
TOKEN_KIND_PAR_RIGHT,
TOKEN_KIND_NUMBER,
TOKEN_KIND_SYMBOL,
} TokenKind;
typedef struct s_Token {
TokenKind kind;
Nob_String_View data;
} Token;
typedef struct s_Tokens {
Token *items;
size_t count;
size_t capacity;
} Tokens;
typedef enum e_NodeKind {
NODE_KIND_SYMBOL,
NODE_KIND_LIST,
NODE_KIND_NUMBER,
NODE_KIND_FUNCTION,
} NodeKind;
typedef struct s_Node Node;
typedef struct s_Nodes Nodes;
typedef Node *(*lisp_function_ptr)(Nodes *args);
typedef struct s_LispFunction {
Nob_String_View name;
lisp_function_ptr apply;
} LispFunction;
typedef struct s_Node {
NodeKind kind;
union {
Nob_String_View as_symbol;
Nodes *as_list;
long long as_number;
LispFunction as_function;
};
} Node;
struct s_Nodes {
Node *items;
size_t count;
size_t capacity;
};
Node *lisp_function_addition(Nodes *args) {
if (args->count != 2) {
printf("'+' expects two arguments!\n");
return NULL;
}
if (args->items[0].kind != NODE_KIND_NUMBER ||
args->items[1].kind != NODE_KIND_NUMBER) {
printf("'+' can only add numbers, you specified something else!\n");
return NULL;
}
Node *node = malloc(sizeof(Node));
node->kind = NODE_KIND_NUMBER;
intptr_t a = args->items[0].as_number;
intptr_t b = args->items[1].as_number;
node->as_number = a + b;
return node;
}
#include "lisp.h"
static LispFunction globalScope[] = {
(LispFunction){.name = (Nob_String_View){.items = "+", .count = 1},
.apply = lisp_function_addition}};
Node *lisp_function_lookup(Nob_String_View name) {
static Node *lisp_function_lookup(Nob_String_View name) {
for (size_t i = 0; i < NOB_ARRAY_LEN(globalScope); i++) {
if (nob_sv_eq(globalScope[i].name, name)) {
Node *node = malloc(sizeof(Node));
@@ -113,6 +33,33 @@ const char *token_kind_name(TokenKind kind) {
}
}
void node_print(Node node) {
switch (node.kind) {
case NODE_KIND_NUMBER: {
printf("%lld", node.as_number);
} break;
case NODE_KIND_SYMBOL: {
printf(SV_Fmt, SV_Arg(node.as_symbol));
} break;
case NODE_KIND_LIST: {
Nodes *children = node.as_list;
printf("(");
for (size_t i = 0; i < children->count; i++) {
Node node = children->items[i];
node_print(node);
if (i != children->count - 1) {
printf(" ");
}
}
printf(")");
} break;
case NODE_KIND_FUNCTION: {
LispFunction func = node.as_function;
printf(SV_Fmt, SV_Arg(func.name));
} break;
}
}
void tokenize(Nob_String_View content, Tokens *tokens) {
for (size_t i = 0; i < content.count; i++) {
char c = content.data[i];
@@ -149,12 +96,13 @@ void tokenize(Nob_String_View content, Tokens *tokens) {
}
// symbols shouldn't start with a digit
bool condition =
isascii(c) && !isdigit(c) && !isblank(c) && c != '(' && c != ')';
bool condition = isascii(c) && !isdigit(c) && !isblank(c) &&
!iscntrl(c) && c != '(' && c != ')';
while (condition) {
nob_sb_appendf(&sb, "%c", c);
c = content.data[++i];
condition = isascii(c) && !isblank(c) && c != '(' && c != ')';
condition = isascii(c) && !isblank(c) && !iscntrl(c) && c != '(' &&
c != ')';
}
if (sb.count > 0) {
@@ -232,33 +180,6 @@ Node *parse(Tokens *tokens) {
return node;
}
void node_print(Node node) {
switch (node.kind) {
case NODE_KIND_NUMBER: {
printf("%lld", node.as_number);
} break;
case NODE_KIND_SYMBOL: {
printf(SV_Fmt, SV_Arg(node.as_symbol));
} break;
case NODE_KIND_LIST: {
Nodes *children = node.as_list;
printf("(");
for (size_t i = 0; i < children->count; i++) {
Node node = children->items[i];
node_print(node);
if (i != children->count - 1) {
printf(" ");
}
}
printf(")");
} break;
case NODE_KIND_FUNCTION: {
LispFunction func = node.as_function;
printf(SV_Fmt, SV_Arg(func.name));
} break;
}
}
Node *eval(Node *node) {
if (node == NULL)
return NULL;
@@ -297,33 +218,3 @@ Node *eval(Node *node) {
}
return NULL;
}
int main(int argc, char **argv) {
if (argc < 2)
return 1;
argv++;
const char *line = *argv++;
Nob_String_View view = nob_sv_from_cstr(line);
Tokens tokens = {0};
tokenize(view, &tokens);
#if 0
for (size_t i = 0; i < tokens.count; i++) {
Token tok = tokens.items[i];
printf("Token(kind=%s, data=" SV_Fmt ")\n", token_kind_name(tok.kind),
SV_Arg(tok.data));
}
#endif
Node *result = parse(&tokens);
if (result == NULL)
return 1;
result = eval(result);
node_print(*result);
printf("\n");
return 0;
}
+66
View File
@@ -0,0 +1,66 @@
#ifndef LISP_H
#define LISP_H
#include "nob.h"
typedef enum e_TokenKind {
TOKEN_KIND_PAR_LEFT,
TOKEN_KIND_PAR_RIGHT,
TOKEN_KIND_NUMBER,
TOKEN_KIND_SYMBOL,
} TokenKind;
typedef struct s_Token {
TokenKind kind;
Nob_String_View data;
} Token;
typedef struct s_Tokens {
Token *items;
size_t count;
size_t capacity;
} Tokens;
typedef enum e_NodeKind {
NODE_KIND_SYMBOL,
NODE_KIND_LIST,
NODE_KIND_NUMBER,
NODE_KIND_FUNCTION,
} NodeKind;
typedef struct s_Node Node;
typedef struct s_Nodes Nodes;
typedef Node *(*lisp_function_ptr)(Nodes *args);
typedef struct s_LispFunction {
Nob_String_View name;
lisp_function_ptr apply;
} LispFunction;
typedef struct s_Node {
NodeKind kind;
union {
Nob_String_View as_symbol;
Nodes *as_list;
long long as_number;
LispFunction as_function;
};
} Node;
struct s_Nodes {
Node *items;
size_t count;
size_t capacity;
};
const char *token_kind_name(TokenKind kind);
void node_print(Node node);
void tokenize(Nob_String_View content, Tokens *tokens);
Node *parse(Tokens *tokens);
Node *eval(Node *node);
// builtins
Node *lisp_function_addition(Nodes *args);
#endif // LISP_H
+34
View File
@@ -0,0 +1,34 @@
#include <stdio.h>
#define NOB_IMPLEMENTATION
#include "lisp.h"
int main(int argc, char **argv) {
if (argc < 2)
return 1;
argv++;
const char *line = *argv++;
Nob_String_View view = nob_sv_from_cstr(line);
Tokens tokens = {0};
tokenize(view, &tokens);
#if 0
for (size_t i = 0; i < tokens.count; i++) {
Token tok = tokens.items[i];
printf("Token(kind=%s, data=" SV_Fmt ")\n", token_kind_name(tok.kind),
SV_Arg(tok.data));
}
#endif
Node *result = parse(&tokens);
if (result == NULL)
return 1;
result = eval(result);
node_print(*result);
printf("\n");
return 0;
}
+18
View File
@@ -0,0 +1,18 @@
(
println (
let (
(x 2)
)
(
cond
(
(= x 2)
5
)
(
else
1
)
)
)
)