commit 3de0de13e88e769bd932c4015d2cc56c859d0258
parent b12b357e5400e077c52bd848f66fd8c0bf7c33d8
Author: citbl <citbl@citbl.org>
Date: Sun, 17 May 2026 21:07:07 +1000
yeap.
Diffstat:
13 files changed, 204 insertions(+), 0 deletions(-)
diff --git a/mtcc/.gitignore b/mtcc/.gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+*.dSYM
diff --git a/mtcc/makefile b/mtcc/makefile
@@ -0,0 +1,11 @@
+MAKEFLAGS += --silent
+
+default:
+ clang -O1 -Wall -Wextra -Wpedantic -std=c99 \
+ -Werror=declaration-after-statement \
+ -o mtcc **/*.c
+ ./mtcc target.mty
+
+clean:
+ rm -rf *.dSYM
+ rm -rf mtcc
diff --git a/mtcc/mtcc b/mtcc/mtcc
Binary files differ.
diff --git a/mtcc/src/array.h b/mtcc/src/array.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ARRAY_PUSH(dest, len, cap, item) \
+ do { \
+ size_t arr_newcap, arr_itemsize; \
+ void *arr_newptr; \
+ if ((len) >= (cap)) { \
+ arr_newcap = (cap) == 0 ? 256 : (cap) * 2; \
+ arr_itemsize = sizeof(*(dest)); \
+ if (arr_newcap <= (cap) || arr_newcap > SIZE_MAX / arr_itemsize) { \
+ fprintf(stderr, "array: capacity overflow (cap=%zu)\n", (size_t)(cap)); \
+ exit(1); \
+ } \
+ \
+ arr_newptr = realloc((dest), arr_newcap * arr_itemsize); \
+ if (!arr_newptr) { \
+ fprintf(stderr, "array: could not reallocate\n"); \
+ exit(1); \
+ } \
+ (dest) = arr_newptr; \
+ (cap) = arr_newcap; \
+ } \
+ \
+ (dest)[(len)++] = (item); \
+ } while (0)
+
+// similar but with the +1 size check and null delimiter at the end!
+#define STRING_PUSH(dest, len, cap, item) \
+ do { \
+ size_t arr_newcap, arr_itemsize; \
+ void *arr_newptr; \
+ if ((len) + 1 >= (cap)) { /* +1 */ \
+ arr_newcap = (cap) == 0 ? 256 : (cap) * 2; \
+ arr_itemsize = sizeof(*(dest)); \
+ if (arr_newcap <= (cap) || arr_newcap > SIZE_MAX / arr_itemsize) { \
+ fprintf(stderr, "array: capacity overflow (cap=%zu)\n", (size_t)(cap)); \
+ exit(1); \
+ } \
+ \
+ arr_newptr = realloc((dest), arr_newcap * arr_itemsize); \
+ if (!arr_newptr) { \
+ fprintf(stderr, "array: could not reallocate\n"); \
+ exit(1); \
+ } \
+ (dest) = arr_newptr; \
+ (cap) = arr_newcap; \
+ } \
+ \
+ (dest)[(len)++] = (item); \
+ (dest)[(len)] = '\0'; \
+ } while (0)
diff --git a/mtcc/src/lexer.c b/mtcc/src/lexer.c
@@ -0,0 +1 @@
+#include "lexer.h"
diff --git a/mtcc/src/lexer.h b/mtcc/src/lexer.h
@@ -0,0 +1,9 @@
+#pragma once
+#include "token.h"
+
+typedef struct {
+ char* filename;
+ token_t* tokens;
+ size_t tok_len;
+ size_t tok_cap;
+} lexer_t;
diff --git a/mtcc/src/main.c b/mtcc/src/main.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include "utils.h"
+#include "token.h"
+
+int main(int argc, char **argv) {
+ const char *filename;
+ const char *contents;
+
+ if (argc < 2) {
+ printf("usage: ./mtcc <filename.mty>\n");
+ return 0;
+ }
+
+ filename = argv[1];
+ contents = read_file(filename);
+
+ printf("%s\n", contents);
+}
diff --git a/mtcc/src/str.c b/mtcc/src/str.c
@@ -0,0 +1,6 @@
+#include "str.h"
+#include "array.h"
+
+void str_append(Str *str, const char c) {
+ STRING_PUSH(str->value, str->len, str->cap, c);
+}
diff --git a/mtcc/src/str.h b/mtcc/src/str.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <stddef.h>
+
+typedef struct Str {
+ char *value;
+ size_t len;
+ size_t cap;
+} Str;
+
+void str_append(Str *str, const char c);
diff --git a/mtcc/src/token.h b/mtcc/src/token.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <stddef.h>
+
+typedef enum {
+ T_IDENT,
+} token_type_t;
+
+typedef struct {
+ token_type_t token_type;
+
+ struct {
+ char *filename;
+ size_t line;
+ size_t col;
+ } span_t;
+
+} token_t;
diff --git a/mtcc/src/utils.c b/mtcc/src/utils.c
@@ -0,0 +1,55 @@
+#include "utils.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *read_file(const char *filename) {
+ long fsize;
+ char *source;
+ FILE *fp = fopen(filename, "rb");
+ if (fp == NULL) {
+ fprintf(stderr, "file not found\n");
+ return NULL;
+ }
+
+ if (fseek(fp, 0, SEEK_END) != 0) {
+ fprintf(stderr, "could not read file\n");
+ fclose(fp);
+ exit(1);
+ }
+
+ fsize = ftell(fp);
+ if (fsize < 0) {
+ fprintf(stderr, "could not read size of file to load\n");
+ fclose(fp);
+ exit(1);
+ }
+ fseek(fp, 0, SEEK_SET);
+
+ source = malloc(fsize + 1);
+ if (!source) {
+ fprintf(stderr, "could not allocate memory to read file\n");
+ exit(1);
+ }
+ fread(source, fsize, 1, fp);
+ fclose(fp);
+
+ source[fsize] = '\0';
+ return source;
+}
+
+void separate_file_from_path(const char *fullpath, char **out_path, char **out_filename) {
+ char *path = strdup(fullpath);
+ char *filename = strrchr(path, '/');
+
+ if (filename == NULL) {
+ printf("No path found\n");
+ exit(1);
+ }
+
+ *filename = '\0';
+ filename++;
+ *out_path = strdup(path);
+ *out_filename = strdup(filename);
+ free(path);
+}
diff --git a/mtcc/src/utils.h b/mtcc/src/utils.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <stdbool.h>
+
+const char *read_file(const char *filename);
+
+void separate_file_from_path(const char *fullpath, char **out_path, char **out_filename);
diff --git a/mtcc/target.mty b/mtcc/target.mty
@@ -0,0 +1,12 @@
+int add(int a, int b) =
+ a + b
+int main() ::
+ ret add(1, 2)
+
+// target QBE:
+
+//export function w $add(w %a, w %b) {
+//@start
+// %r =w add %a, %b
+// ret %r
+//}