commit 1db4b03a50474862ea143ad3bbe586f3feb03dd9
parent c3b65f7f8688d268cac9e824c14428d867a56286
Author: citbl <citbl@citbl.org>
Date: Sat, 23 May 2026 23:27:55 +1000
lexer line/col
Diffstat:
4 files changed, 137 insertions(+), 22 deletions(-)
diff --git a/mtcl/lexer.lua b/mtcl/lexer.lua
@@ -19,6 +19,10 @@ function alpha_num(c)
return is_alpha(c) or is_digit(c)
end
+function is_space(c)
+ return c == "\t" or c == "\n" or c == " " or c == "\r"
+end
+
function read_ident(start, src)
local word = ""
local i = start
@@ -67,20 +71,31 @@ TK = {
EQEQ = "equality",
L_PAREN = "l paren",
R_PAREN = "r paren",
- DBL_QUOTE = "dbl quote",
- SGL_QUOTE = "sgl quote",
- LIT_FLOAT = "float lit",
- LIT_INT = "int lit",
+ DBL_QUOTE = "dbl quo",
+ SGL_QUOTE = "sgl quo",
+ LIT_FLOAT = "a float",
+ LIT_INT = "a int",
}
-Token = { kind = TK.IDK }
+Token = { kind = TK.IDK, file = "", line = 0, col = 0 }
local function print_token(t)
- print("type: " .. t.kind .. "\t value: " .. t.lexeme)
+ print(
+ t.file
+ .. " L"
+ .. t.line
+ .. ":"
+ .. t.col
+ .. " \t type: "
+ .. t.kind
+ .. "\t value: "
+ .. t.lexeme
+ )
end
-function lexer:lex(src)
+function lexer:lex(file, src)
local i = 1
+ local line, col = 1, 1
local tokens = {}
local function next()
@@ -92,46 +107,139 @@ function lexer:lex(src)
while i <= #src do
local c = src:sub(i, i)
- if c == "\t" or c == "\n" or c == " " or c == "\r" then
- -- nothing
+ if is_space(c) then
+ -- skip...
+ if c == "\n" then
+ col = 1
+ line = line + 1
+ else
+ col = col + 1
+ end
elseif is_alpha(c:byte()) then
word, i = read_ident(i, src)
- tokens[#tokens + 1] = { kind = TK.IDENT, lexeme = word }
+ col = i
+ tokens[#tokens + 1] = {
+ kind = TK.IDENT,
+ lexeme = word,
+ file = file,
+ line = line,
+ col = col,
+ }
elseif is_digit(c:byte()) then
number, i, is_float = read_number(i, src)
+ col = i
local kind = TK.IDK
if is_float then
kind = TK.LIT_FLOAT
else
kind = TK.LIT_INT
end
- tokens[#tokens + 1] = { kind = kind, lexeme = number }
+ tokens[#tokens + 1] = {
+ kind = kind,
+ lexeme = number,
+ file = file,
+ line = line,
+ col = col,
+ }
elseif c == ":" then
if next() == ":" then
- tokens[#tokens + 1] = { kind = TK.COLONCOLON, lexeme = "::" }
+ tokens[#tokens + 1] = {
+ kind = TK.COLONCOLON,
+ lexeme = "::",
+ file = file,
+ line = line,
+ col = col,
+ }
i = i + 1
+ col = col + 1
else
- tokens[#tokens + 1] = { kind = TK.COLON, lexeme = ":" }
+ tokens[#tokens + 1] = {
+ kind = TK.COLON,
+ lexeme = ":",
+ file = file,
+ line = line,
+ col = col,
+ }
end
elseif c == "=" then
if next() == "=" then
- tokens[#tokens + 1] = { kind = TK.EQEQ, lexeme = "==" }
+ tokens[#tokens + 1] = {
+ kind = TK.EQEQ,
+ lexeme = "==",
+
+ file = file,
+ line = line,
+ col = col,
+ }
i = i + 1
+ col = col + 1
else
- tokens[#tokens + 1] = { kind = TK.EQ, lexeme = "=" }
+ tokens[#tokens + 1] = {
+ kind = TK.EQ,
+ lexeme = "=",
+
+ file = file,
+ line = line,
+ col = col,
+ }
end
elseif c == "(" then
- tokens[#tokens + 1] = { kind = TK.L_PAREN, lexeme = "(" }
+ tokens[#tokens + 1] = {
+ kind = TK.L_PAREN,
+ lexeme = "(",
+
+ file = file,
+ line = line,
+ col = col,
+ }
+ i = i + 1
+ col = col + 1
elseif c == ")" then
- tokens[#tokens + 1] = { kind = TK.R_PAREN, lexeme = ")" }
+ tokens[#tokens + 1] = {
+ kind = TK.R_PAREN,
+ lexeme = ")",
+
+ file = file,
+ line = line,
+ col = col,
+ }
+ i = i + 1
+ col = col + 1
elseif c == "'" then
- tokens[#tokens + 1] = { kind = TK.SGL_QUOTE, lexeme = "'" }
+ tokens[#tokens + 1] = {
+ kind = TK.SGL_QUOTE,
+ lexeme = "'",
+
+ file = file,
+ line = line,
+ col = col,
+ }
+ i = i + 1
+ col = col + 1
elseif c == '"' then
- tokens[#tokens + 1] = { kind = TK.DBL_QUOTE, lexeme = '"' }
+ tokens[#tokens + 1] = {
+ kind = TK.DBL_QUOTE,
+ lexeme = '"',
+
+ file = file,
+ line = line,
+ col = col,
+ }
+ i = i + 1
+ col = col + 1
else
- tokens[#tokens + 1] = { kind = TK.IDK, lexeme = "" }
+ tokens[#tokens + 1] = {
+ kind = TK.IDK,
+ lexeme = "",
+ file = file,
+ line = line,
+ col = col,
+ }
+ i = i + 1
+ col = col + 1
end
i = i + 1
+ col = col + 1
end
for i = 1, #tokens do
diff --git a/mtcl/main.lua b/mtcl/main.lua
@@ -2,9 +2,10 @@
local lexer = require("lexer")
-local file = io.open(arg[1], "rb")
+local filename = arg[1] -- TODO check
+local file = io.open(filename, "rb")
local contents = file:read("*all")
-lexer:lex(contents)
+lexer:lex(filename, contents)
print(#lexer.tokens .. " tokens")
diff --git a/mtcl/makefile b/mtcl/makefile
@@ -3,3 +3,6 @@ MAKEFLAGS += --silent
default:
lua main.lua target.mty
stylua --column-width 80 .
+
+fmt:
+ stylua --column-width 80 .
diff --git a/mtcl/parser.lua b/mtcl/parser.lua
@@ -0,0 +1,3 @@
+local parser = {}
+
+function parser:parse(filename, src, parser) end