summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2023-01-08 10:00:08 -0800
committerPreston Pan <preston@nullring.xyz>2023-01-08 10:00:08 -0800
commitaa1dd020edb82f26dd5bc29378177cfcaa4c53ed (patch)
tree4785b6311ac14be5939d33ebb5b0d8988c8f56bd
parent8edafecb633fec2b6327d996c1e7c282f4f1792f (diff)
print functions completed
-rw-r--r--.gitignore2
-rw-r--r--README.md13
-rw-r--r--doc/main.nxs2
-rw-r--r--src/lexer.c4
-rw-r--r--src/main.c2
-rw-r--r--src/print.c48
-rw-r--r--src/visitor.c1
7 files changed, 26 insertions, 46 deletions
diff --git a/.gitignore b/.gitignore
index 10bc2bc..e62acfd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
nxs
diffs/**
-hash_table_new.c
+*.swp
diff --git a/README.md b/README.md
index 25e5db9..15a5257 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ This is basically a scheme-like language that is aimed to
be scheme with no additional fluff. The programming language
is "done" now in the sense that it is turing complete and
there are some features like strings, ints, floats, booleans, and
-some built-in functions to make he language usable, though
+some built-in functions to make the language usable, though
I plan to add support for macros and other stuff. This
is a functional programming language so functions are first-class.
@@ -14,7 +14,7 @@ the ones that I have not, and that is simply because I
made this checklist after I did everything in the first
checklist.
-Estimate: 90% done.
+Estimate: 95% done.
### DONE
- [X] Write the lexer (easy)
@@ -22,13 +22,14 @@ Estimate: 90% done.
- [X] Write hash table (medium)
- [X] Write the visitor (hard)
- [X] Write a few print functions (trivial)
+- [X] Write the print function for lists (trivial)
+- [X] Implement a primitive include system (easy-medium)
### NOT DONE
-- [ ] Write the print function for lists (trivial)
-- [ ] Implement macros (medium)
-- [ ] Implement a primitive include system (easy-medium)
- [ ] Finish type conversion builtins (easy)
- [ ] Finish read and write builtins (easy)
+- [ ] Make appealing frontend (easy)
+- [ ] Implement macros (medium)
### Wishlist
- [ ] Maybe a garbage collector?
@@ -51,7 +52,7 @@ Programming in this language, you may find some differences from scheme. Here ar
You may find actual code examples in `doc/`. Also, there will be more functionality than
the above, but I have not implemented it yet. Some future ones are:
-8. The only side effects are printing evaluated expressions and writing to files with the `write` builtin.
+8. The only side effects are printing expressions with the `print` builtin and writing to files with the `write` builtin.
9. You may define macros.
10. Let's all have fun and play together!
diff --git a/doc/main.nxs b/doc/main.nxs
index 3dd0ebf..d3aa986 100644
--- a/doc/main.nxs
+++ b/doc/main.nxs
@@ -4,3 +4,5 @@
(if (= n 0) 1 (* n (factorial (print(- n 1)))))))
(print(fib 7))
(print (+ (factorial 5) 10))
+
+(print(car (quote (+ (3 2) 4))))
diff --git a/src/lexer.c b/src/lexer.c
index 29c6542..e58197a 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -26,7 +26,7 @@ lexer_t *init_lexer(char *source) {
}
void lexer_move(lexer_t *lexer) {
- if (lexer->c != '\0') {
+ if (lexer->c != '\0' && lexer->c != EOF) {
lexer->i++;
lexer->c = lexer->source[lexer->i];
if (lexer->c == '\n') {
@@ -39,7 +39,7 @@ void lexer_move(lexer_t *lexer) {
void lexer_ignore_whitespace(lexer_t *lexer) {
while (isspace(lexer->c)) {
- if (lexer->c == '\0')
+ if (lexer->c == '\0' || lexer->c == EOF)
return;
lexer_move(lexer);
}
diff --git a/src/main.c b/src/main.c
index db5846d..c75ef85 100644
--- a/src/main.c
+++ b/src/main.c
@@ -132,7 +132,7 @@ int main(int argc, char **argv) {
exit(1);
}
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
- printf("nxs, version 1.0.0 alpha\n");
+ printf("nxs, version 1.2 alpha\n");
exit(0);
}
diff --git a/src/print.c b/src/print.c
index b2d4f32..65cfb66 100644
--- a/src/print.c
+++ b/src/print.c
@@ -2,56 +2,32 @@
#include "./include/ast.h"
#include <stdio.h>
-void print_string(ast_t *str) { printf("%s\n", str->string_value); }
+void print_string(ast_t *str) { printf("%s", str->string_value); }
-void print_int(ast_t *i) { printf("%d\n", i->int_value); }
+void print_int(ast_t *i) { printf("%d", i->int_value); }
void print_bool(ast_t *b) {
if (b->bool_value)
- printf("T\n");
+ printf("T");
else
- printf("F\n");
+ printf("F");
}
-void print_float(ast_t *f) { printf("%f\n", f->float_value); }
+void print_float(ast_t *f) { printf("%f", f->float_value); }
-void print_symbol(ast_t *s) { printf("S: %s\n", s->string_value); }
+void print_symbol(ast_t *s) { printf(":%s", s->string_value); }
void print_func(ast_t *f) { print_pair(f->cdr); }
void print_pair(ast_t *p) {
printf("(");
ast_t *cur = p;
- bool is_last = false;
-
- while (cur != NULL && (cur->cdr != NULL && cur->cdr->car != NULL)) {
- if (cur->cdr == NULL) {
- is_last = true;
- }
- switch (cur->car->type) {
- case AST_STRING:
- printf("%s", cur->car->string_value);
- break;
- case AST_INT:
- printf("%d", cur->car->int_value);
- break;
- case AST_FLOAT:
- printf("%d", cur->car->int_value);
- break;
- case AST_BOOL:
- printf("%d", cur->car->int_value);
- break;
- case AST_FUNCTION:
- break;
- case AST_SYMBOL:
- printf("%d", cur->car->int_value);
- break;
- case AST_PAIR:
- printf("%d", cur->car->int_value);
- break;
- case AST_ROOT:
- break;
- }
+ while (cur != NULL && (cur->cdr != NULL && cur->car != NULL)) {
+ print(cur->car);
+ if (cur->cdr->cdr != NULL) {
+ printf(" ");
+ } else
+ printf(")");
cur = cur->cdr;
}
}
diff --git a/src/visitor.c b/src/visitor.c
index 374ad02..6fd487a 100644
--- a/src/visitor.c
+++ b/src/visitor.c
@@ -447,6 +447,7 @@ ast_t *eval_list(visitor_t *v, ast_t *e) {
ast_t *arg1 = eval_expr(v, args->car);
print(arg1);
+ printf("\n");
return arg1;
}