mighty

The mighty programming language, compiler and tools (WIP)
Log | Files | Refs

commit ae90623b362dda650c5c058d588d360121a18d79
parent 6d1a49b04ea41ea43874114884012860d8ee72ea
Author: citbl <citbl@citbl.org>
Date:   Sat, 23 May 2026 17:14:38 +1000

wip

Diffstat:
Amtcc/src/errors.c | 9+++++++++
Amtcc/src/errors.h | 3+++
Mmtcc/src/main.c | 1-
Mmtcc/src/parser.c | 53++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mmtcc/src/token.h | 2+-
Mmtcc/src/types.h | 6++++--
Amtcl/.gitignore | 2++
Amtcl/main.lua | 40++++++++++++++++++++++++++++++++++++++++
Amtcl/makefile | 2++
Amtcl/target.mty | 6++++++
Atest.mty | 49+++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 168 insertions(+), 5 deletions(-)

diff --git a/mtcc/src/errors.c b/mtcc/src/errors.c @@ -0,0 +1,9 @@ +#include <stdio.h> +#include <stdlib.h> +#include "errors.h" + +void +panic(const char *msg) { + fprintf(stderr, "%s\n", msg); + exit(1); +} diff --git a/mtcc/src/errors.h b/mtcc/src/errors.h @@ -0,0 +1,3 @@ +#pragma once + +void panic(const char *msg); diff --git a/mtcc/src/main.c b/mtcc/src/main.c @@ -11,7 +11,6 @@ main(int argc, char **argv) { file_t file; struct lexer lexer; struct parser parser; - if (argc < 2) { const char *cmp = argv[0]; printf("usage: %s <filename.mty>\n", cmp); diff --git a/mtcc/src/parser.c b/mtcc/src/parser.c @@ -1,5 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> #include "parser.h" +#include "errors.h" + +void add_error(struct parser *p, const char *message); +struct token peek(struct parser *p); +struct token consume(struct parser *p); +bool check(struct parser *p, enum token_type type); + +void +parser_parse(struct parser *p) { + // from [x y z] [node + // decl / etc. + // nodes + + while (p->pos < p->lexer->tok_len) { + struct token tok = consume(p); + switch (tok.token_type) { + case TOKEN_IDENT: + struct token type = tok; + if (!check(p, TOKEN_IDENT)) + panic("expected open paren ( after label in function declaration"); + break; + default: + panic("error parsing top level"); + } + } +} + +struct token +peek(struct parser *p) { + if (p->pos >= p->lexer->tok_len) + panic("token peek out of bounds?"); + return p->lexer->tokens[p->pos + 1]; +} + +struct token +consume(struct parser *p) { + struct token tok = p->lexer->tokens[p->pos++]; + if (tok.token_type == 0) panic("consume bad token EOF?"); + return tok; +} + +bool +check(struct parser *p, enum token_type type) { + return (peek(p).token_type == type); +} void -parser_parse(struct parser *parser) { +add_error(struct parser *p, const char *message) { + const char *filename = p->lexer->tokens[p->pos].span.filename; + size_t line = p->lexer->tokens[p->pos].span.line; + size_t col = p->lexer->tokens[p->pos].span.col; + fprintf(stderr, "%s: L%zu:%zu : %s", filename, line, col, message); } diff --git a/mtcc/src/token.h b/mtcc/src/token.h @@ -28,8 +28,8 @@ enum token_type { TOKEN_COLON, TOKEN_COLON_COLON, TOKEN_COMMA, - TOKEN_EOF, TOKEN_EQ, + TOKEN_EOF, TOKEN_LITERAL_BOOL, TOKEN_LITERAL_INT, TOKEN_LITERAL_FLOAT, diff --git a/mtcc/src/types.h b/mtcc/src/types.h @@ -48,6 +48,8 @@ struct node { struct parser { struct lexer *lexer; struct node **nodes; - size_t nodes_len; - size_t nodes_cap; + size_t nodes_len, nodes_cap; + size_t pos; + size_t err_len, err_cap; + char *errors; }; diff --git a/mtcl/.gitignore b/mtcl/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +*.lua~ diff --git a/mtcl/main.lua b/mtcl/main.lua @@ -0,0 +1,40 @@ +-- comp + +local file = io.open(arg[1], "rb") +local contents = file:read("*all") + +function skip() end +function read_ident(start, c, str) + local a = string.byte("a") + local z = string.byte("z") + local A = string.byte("A") + local Z = string.byte("Z") + local zero = string.byte("0") + local nine = string.byte("9") + for i = start, #str do + local c = src:sub(i,i) + end +end + +function lex(src) + local i = 1 + local whitespacers = { + ["\t"] = skip, + ["\r"] = skip, + ["\n"] = skip, + [" "] = skip, + } + + for i = 1, #src do + local c = src:sub(i, i) + local char_fx = whitespacers[c] + + if char_fx then + char_fx() + else + print(c) + end + end +end + +lex(contents) diff --git a/mtcl/makefile b/mtcl/makefile @@ -0,0 +1,2 @@ +default: + lua main.lua target.mty diff --git a/mtcl/target.mty b/mtcl/target.mty @@ -0,0 +1,6 @@ +use std + +fx main :: int = + print("hello") + ret 0 + diff --git a/test.mty b/test.mty @@ -0,0 +1,49 @@ +fn is_alpha :: (>= 'a' && <= 'z') || (>= 'A' && <= 'z') + +fx main :: + with []Token tokens + with contents = read_file filename | split + @ match + '+' => tokens += (Token){.type = PLUS} + '-' => tokens += (Token){.type = MINUS} + is_alpha => tokens += parse @+ + ??? => throw("unknown token") + +fx main :: print "hello" // "hello" + +fx main :: with "hello" print // hello + +fx main :: with "hello" | split @ print // [h e l l o] + +fx sub :: T1 - T2 + +fx main :: print "hello, world!" + + +fx add :: int, int -> int = A + B +fx sub :: int, int -> int = A - B +fx err :: str = + fprintf(std.err, str) + exit 1 + +// terse, readable, reliable, enjoyable + +use lexer + +fx main :: int = + filename := std.args[1] + contents := std.read_file(filename) + tokens := lexer.lex(contents) + print_tokens(tokens) + +ns lexer + +fx lex :: str contents = + @[contents] + | ignore_whitespace + | parse_idents + | parse_chars + +fn parse_idents :: char x = + static str word = "" +