summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorczjstmax <jstmaxlol@disroot.org>2026-02-14 18:43:14 +0100
committerczjstmax <jstmaxlol@disroot.org>2026-02-14 18:43:14 +0100
commit2b885f00df619b77bbfcee3ff209cefe4a277df2 (patch)
treef2c5bf0452d350987cc668228d3588493090161d /src
parent9201d978d0c4d4f4bdffd4e686ef116d7fdaa982 (diff)
Cumulative update.
Signed-off-by: czjstmax <jstmaxlol@disroot.org>
Diffstat (limited to 'src')
-rw-r--r--src/heads/abstract.h118
-rw-r--r--src/heads/codegen.h4
-rw-r--r--src/heads/freeast.h34
-rw-r--r--src/rbc.c78
4 files changed, 166 insertions, 68 deletions
diff --git a/src/heads/abstract.h b/src/heads/abstract.h
index efecaa0..3140742 100644
--- a/src/heads/abstract.h
+++ b/src/heads/abstract.h
@@ -1,6 +1,7 @@
-#ifndef CRBC_ABSTR
-#define CRBC_ABSTR
+#ifndef CRBC_ABSTR_H
+#define CRBC_ABSTR_H
+#include <stdio.h> // FILE, fprintf()
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
@@ -12,39 +13,64 @@ enum ExprKind {
EXPR_IDENT
};
-typedef struct Expr {
+// fwd.
+typedef struct Expr Expr;
+typedef struct ExprInt ExprInt;
+typedef struct ExprChar ExprChar;
+typedef struct ExprBool ExprBool;
+typedef struct ExprString ExprString;
+typedef struct ExprIdent ExprIdent;
+typedef struct ExprBinary ExprBinary;
+
+struct Expr {
enum ExprKind kind;
- void *as;
-} Expr;
+ union {
+ ExprInt *intLiteral;
+ ExprBool *boolLiteral;
+ ExprChar *charLiteral;
+ ExprString *stringLiteral;
+ ExprIdent *ident;
+ } as;
+};
-typedef struct ExprInt {
+struct ExprInt {
int value;
-} ExprInt;
+};
//
-typedef struct ExprChar {
+struct ExprChar {
char value;
-} ExprChar;
+};
//
-typedef struct ExprBool {
+struct ExprBool {
bool value;
-} ExprBool;
+};
//
-typedef struct ExprString {
+struct ExprString {
char *value;
-} ExprString;
+};
//
-typedef struct ExprIdent {
+struct ExprIdent {
char *name;
-} ExprIdent;
+};
+//
+struct ExprBinary {
+ Expr *left;
+ Expr *right;
+ char op;
+};
// ===== STATEMENTS =====
-typedef struct Stmt {
+
+typedef struct Stmt Stmt;
+typedef struct Block Block;
+
+struct Stmt {
int _dummy;
-} Stmt;
+};
-typedef struct Block {
+struct Block {
int _dummy;
-} Block;
+};
// ===== DECLARATIONS =====
enum DeclKind {
@@ -55,48 +81,60 @@ enum DeclKind {
DECL_TYPE_UNION
};
-typedef struct Decl {
+// fwd.
+typedef struct Decl Decl;
+typedef struct DeclVar DeclVar;
+typedef struct DeclFunc DeclFunc;
+typedef struct DeclTypeStruct DeclTypeStruct;
+typedef struct EnumMember EnumMember;
+typedef struct DeclTypeEnum DeclTypeEnum;
+typedef struct DeclTypeUnion DeclTypeUnion;
+
+struct Decl {
enum DeclKind kind;
- void *as;
-} Decl;
+ union {
+ DeclVar *var;
+ DeclFunc *func;
+ DeclTypeStruct *typeStruct;
+ DeclTypeEnum *typeEnum;
+ DeclTypeUnion *typeUnion;
+ } as;
+};
// variable declaration
-typedef struct DeclVar {
+struct DeclVar {
char *ident;
char *type; // TODO: replace with Type*
Expr *init; // NULL => declaration only
-} DeclVar;
+};
-// function declaration
-typedef struct DeclFunc {
+struct DeclFunc {
char *ident;
char *return_type; // NULL => inferred
char *params; // TODO: param list
Block *body; // NULL => forward declaration
-} DeclFunc;
+};
-// struct type declaration
-typedef struct DeclTypeStruct {
+struct DeclTypeStruct {
char *ident;
char *members; // TODO: member list
-} DeclTypeStruct;
+};
-// enum type declaration
-typedef struct EnumMember {
+struct EnumMember {
char *name;
char *value; // NULL => implicit
-} EnumMember;
+};
-typedef struct DeclTypeEnum {
+struct DeclTypeEnum {
char *ident;
EnumMember *members;
-} DeclTypeEnum;
+};
// union type declaration
-typedef struct DeclTypeUnion {
+struct DeclTypeUnion {
char *ident;
char *members; // TODO: member list
-} DeclTypeUnion;
+};
// ===== FUNCTIONS =====
static inline Decl *DeclareVariable(const char *ident, const char *type, Expr *init) {
@@ -108,7 +146,7 @@ static inline Decl *DeclareVariable(const char *ident, const char *type, Expr *i
var->init = init;
decl->kind = DECL_VAR;
- decl->as = var;
+ decl->as.var = var;
return decl;
}
@@ -119,8 +157,8 @@ static inline Expr *ExprIntLiteral(int value) {
lit->value = value;
- expr->kind = EXPR_INT;
- expr->as = lit;
+ expr->kind = EXPR_INT;
+ expr->as.intLiteral = lit;
return expr;
}
diff --git a/src/heads/codegen.h b/src/heads/codegen.h
index d629caf..17053e3 100644
--- a/src/heads/codegen.h
+++ b/src/heads/codegen.h
@@ -1,5 +1,5 @@
-#ifndef CRBC_CODEGEN
-#define CRBC_CODEGEN
+#ifndef CRBC_CODEGEN_H
+#define CRBC_CODEGEN_H
// Header file for CReborn's Codegen API
diff --git a/src/heads/freeast.h b/src/heads/freeast.h
index 544d183..c52e4e8 100644
--- a/src/heads/freeast.h
+++ b/src/heads/freeast.h
@@ -1,5 +1,5 @@
-#ifndef CRBC_FREEAST
-#define CRBC_FREEAST
+#ifndef CRBC_FREEAST_H
+#define CRBC_FREEAST_H
// Free memory functions, utilize after having used the AST
@@ -10,19 +10,21 @@ void FreeExpr(Expr *expr)
if (!expr) return;
switch (expr->kind) {
- case EXPR_INT:
- free(expr->as);
- break;
- case EXPR_BOOL:
- break;
- case EXPR_CHAR:
- break;
- case EXPR_STRING:
- break;
- case EXPR_IDENT:
- break;
- default:
- break;
+ case EXPR_INT:
+ free(expr->as.intLiteral);
+ break;
+ case EXPR_BOOL:
+ free(expr->as.boolLiteral);
+ break;
+ case EXPR_CHAR:
+ free(expr->as.charLiteral);
+ break;
+ case EXPR_STRING:
+ free(expr->as.stringLiteral);
+ break;
+ case EXPR_IDENT:
+ free(expr->as.ident);
+ break;
}
free(expr);
@@ -44,7 +46,7 @@ void FreeDecl(Decl *decl)
switch (decl->kind) {
case DECL_VAR:
- FreeDeclVar((DeclVar *)decl->as);
+ FreeDeclVar(decl->as.var);
break;
case DECL_FUNC:
diff --git a/src/rbc.c b/src/rbc.c
index 1e6a3de..7fda8f2 100644
--- a/src/rbc.c
+++ b/src/rbc.c
@@ -27,16 +27,16 @@
* You can also obviously also set this in your .vimrc.
*
* - For Vim users that want to (a)llow the local .exrc for commodity, you can just do:
- * :set exrc secure
- * and reopen any file in the repo, then you will be asked to (a)llow, meaning to trust this
- * repo's .exrc, after (a)llowing it you will already have the 4 spaces indentation, the 100
- * characters limit (textwidth limit) and the format options set automatically. This only applies
- * when editing files from this repo, but if you want them in your global .vimrc or neovim config
- * you can also copy them, again, from the local .exrc file.
+ * :set exrc nosecure
+ * and reopen any file in the repo, then you will be asked to (a)llow, meaning to trust this
+ * repo's .exrc, after (a)llowing it you will already have the 4 spaces indentation, the 100
+ * characters limit (textwidth limit) and the format options set automatically. This only
+ * applies when editing files from this repo, but if you want them in your global .vimrc or
+ * neovim config you can also copy them, again, from the local .exrc file.
*
* - Note: If you use vim/nvim and you loaded (allowed) the .exrc from this repo you can also use
- * these commands that will automatically compile for either release / normal mode testing or for
- * debugging mode.
+ * these commands that will automatically compile for either release / normal mode testing
+ * or for debugging mode.
*
* :Cn / :Compn - Compiles with 'Normal compile'
* :Cd / :Compd - Compiles with 'Debug compile'
@@ -70,11 +70,15 @@
//
// local / helpers
static inline int Eval(int x);
+static inline void EmitExpr(Expr *expr, FILE *out);
+static inline void EmitDeclVar(DeclVar *v, FILE *out);
// main
int main(int argc, char **argv) {
printf(":> Checking for arguments...\n");
+
if (argc >= 2) {
+ // mostly debug info
for (int i = 1; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
@@ -82,6 +86,9 @@ int main(int argc, char **argv) {
printf(":> No arguments were found. (%d)\n\n", argc-1);
}
+ // TODO: remove this, added for clarity
+ printf("\n");
+
const char *identBuff = "number";
const char *typeBuff = "int";
@@ -100,7 +107,7 @@ int main(int argc, char **argv) {
Decl *decl = DeclareVariable(identBuff, typeBuff, e);
if (decl->kind == DECL_VAR) {
- DeclVar *v = decl->as;
+ DeclVar *v = decl->as.var;
printf("v->ident=%s, v->type=%s\nlet %s: %s = %d;", v->ident, v->type, v->ident, v->type, valueBuff);
}
@@ -113,9 +120,60 @@ int main(int argc, char **argv) {
// Functions (definitions)
//
static inline int Eval(int x) {
- // TODO
+ // TODO:
// (work on this after AST is finished)
return x;
}
+void EmitExpr(Expr *expr, FILE *out) {
+ if (!expr) return;
+
+ switch (expr->kind) {
+
+ case EXPR_INT: {
+ ExprInt *lit = expr->as.intLiteral;
+ fprintf(out, "%d", lit->value);
+ break;
+ }
+
+ case EXPR_BOOL: {
+ ExprBool *b = expr->as.boolLiteral;
+ fprintf(out, "%s", b->value ? "1" : "0");
+ break;
+ }
+
+ case EXPR_CHAR: {
+ ExprChar *c = expr->as.charLiteral;
+ fprintf(out, "'%c'", c->value);
+ break;
+ }
+
+ case EXPR_STRING: {
+ ExprString *s = expr->as.stringLiteral;
+ fprintf(out, "\"%s\"", s->value);
+ break;
+ }
+
+ case EXPR_IDENT: {
+ ExprIdent *id = expr->as.ident;
+ fprintf(out, "%s", id->name);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void EmitDeclVar(DeclVar *v, FILE *out) {
+ fprintf(out, "%s %s", v->type, v->ident);
+
+ if (v->init != NULL) {
+ fprintf(out, " = ");
+ EmitExpr(v->init, out);
+ }
+
+ fprintf(out, ";\n");
+}
+
#endif