mighty

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

commit 308881ef7bfcfa3943a70e24f1a1e5e0a005e1d9
parent 3292841b13ea847c0c384e5709e9e6ad340694f7
Author: keyle <keyle@capsule.org>
Date:   Sat, 16 May 2026 16:39:58 +1000

lexer wip

Diffstat:
Amtc/go.mod | 3+++
Amtc/lexer/lexer.go | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amtc/main.go | 20++++++++++++++++++++
Amtc/makefile | 2++
Amtc/target.mty | 12++++++++++++
Amtc/test.mty | 2++
6 files changed, 224 insertions(+), 0 deletions(-)

diff --git a/mtc/go.mod b/mtc/go.mod @@ -0,0 +1,3 @@ +module mighty + +go 1.26.2 diff --git a/mtc/lexer/lexer.go b/mtc/lexer/lexer.go @@ -0,0 +1,185 @@ +package lexer + +import "fmt" + +type Kind int + +const ( + Ident Kind = iota + Plus + PlusEq + PlusPlus + Colon + ColonColon + Minus + MinusEq + MinusMinus + LParen + RParen + EOF + IntLiteral + FloatLiteral + StringLiteral + CharLiteral + BoolLiteral + BadToken +) + +type Token struct { + Kind Kind + Value string + Line, Col int +} + +func Lex(src string) []Token { + var res []Token + i := 0 + line := 1 + col := 1 + + for i < len(src) { + + c := src[i] + if is_space(c) { + if c == '\n' { + line++ + col = 1 + } else { + col++ + } + i++ + continue + } + + start := i + startCol := col + + if is_alpha(c) || is__(c) { + for i < len(src) && (is_alphanum(src[i]) || is__(src[i])) { + i++ + col++ + } + res = append(res, Token{Ident, src[start:i], line, startCol}) + continue + } + if is_digit(c) { + numeric := IntLiteral + for i < len(src) && (is_digit(src[i]) || is__(src[i]) && is_dot(src[i])) { + if is_dot(src[i]) { + numeric = FloatLiteral + } + i++ + col++ + } + + res = append(res, Token{numeric, src[start:i], line, startCol}) + continue + } + var cx byte + if i+1 < len(src) { + cx = src[i+1] + } + switch c { + case ':': + switch cx { + case ':': + res = append(res, Token{ColonColon, src[i : i+2], line, col}) + i++ + col++ + default: + res = append(res, Token{Colon, src[i : i+1], line, col}) + } + case '+': + switch cx { + case '=': + res = append(res, Token{PlusEq, src[i : i+2], line, col}) + i++ + col++ + case '+': + res = append(res, Token{PlusPlus, src[i : i+2], line, col}) + i++ + col++ + default: + res = append(res, Token{Plus, src[i : i+1], line, col}) + } + case '(': + res = append(res, Token{LParen, src[i : i+1], line, col}) + case ')': + res = append(res, Token{RParen, src[i : i+1], line, col}) + default: + res = append(res, Token{BadToken, src[i : i+1], line, col}) + } + + i++ + col++ + } + res = append(res, Token{EOF, "", line, col}) + return res +} + +func is_space(c byte) bool { + return c == ' ' || c == '\t' || c == '\r' || c == '\n' +} + +func is_alpha(c byte) bool { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' +} + +func is_alphanum(c byte) bool { + return is_alpha(c) || is_digit(c) +} + +func is__(c byte) bool { return c == '_' } +func is_dot(c byte) bool { return c == '.' } + +func is_digit(c byte) bool { + return c >= '0' && c <= '9' +} + +func (k Kind) String() string { + switch k { + case Ident: + return "Ident" + case Plus: + return "Plus" + case PlusEq: + return "PlusEq" + case PlusPlus: + return "PlusPlus" + case Minus: + return "Minus" + case MinusEq: + return "MinusEq" + case MinusMinus: + return "MinusMinus" + case Colon: + return "Colon" + case ColonColon: + return "ColonColon" + case LParen: + return "LParen" + case RParen: + return "RParen" + case EOF: + return "EOF" + case IntLiteral: + return "IntLiteral" + case FloatLiteral: + return "FloatLiteral" + case StringLiteral: + return "StringLiteral" + case CharLiteral: + return "CharLiteral" + case BoolLiteral: + return "BoolLiteral" + case BadToken: + return "BAD~~~TOKEN" + default: + return "Unknown" + } +} +func Print_tokens(tokens []Token) { + for _, tok := range tokens { + fmt.Printf("%-d:%-2d %-12s %-12q\n", tok.Line, tok.Col, tok.Kind, tok.Value) + } +} diff --git a/mtc/main.go b/mtc/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "os" + + l "mighty/lexer" +) + +func main() { + args := os.Args[1:] + fmt.Println(args[0]) + data, err := os.ReadFile(args[0]) + if err != nil { + panic(err) + } + + tokens := l.Lex(string(data)) + l.Print_tokens(tokens) +} diff --git a/mtc/makefile b/mtc/makefile @@ -0,0 +1,2 @@ +default: + go run . test.mty diff --git a/mtc/target.mty b/mtc/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 +} diff --git a/mtc/test.mty b/mtc/test.mty @@ -0,0 +1,2 @@ +int main() :: + io.putln("hello world " + 123)