commit b12b357e5400e077c52bd848f66fd8c0bf7c33d8
parent 0a4448ba4e654bc388fbb558e89afc07e9185167
Author: citbl <citbl@citbl.org>
Date: Sun, 17 May 2026 21:07:00 +1000
future work
Diffstat:
3 files changed, 268 insertions(+), 14 deletions(-)
diff --git a/mtc/lexer/lexer.go b/mtc/lexer/lexer.go
@@ -8,6 +8,28 @@ type Kind int
const (
Ident Kind = iota
+
+ KeywordNs
+ KeywordIn
+ KeywordFrom
+ KeywordUse
+ KeywordFfi
+ KeywordDrop
+ KeywordAs
+ KeywordOf
+ KeywordAnd
+ KeywordOr
+ KeywordRef
+ KeywordStruct
+ KeywordEnum
+ KeywordPre
+ KeywordPost
+ KeywordInv
+ KeywordIf
+ KeywordElse
+ KeywordWhere
+ KeywordPub
+
Dot
Colon
ColonColon
@@ -24,6 +46,10 @@ const (
MinusMinus
LParen
RParen
+ LBrace
+ RBrace
+ LBracket
+ RBracket
Plus
PlusEq
PlusPlus
@@ -32,6 +58,51 @@ const (
BadToken
)
+var kindsKeywords = map[Kind]string{
+ KeywordNs: "ns",
+ KeywordIn: "in",
+ KeywordFrom: "from",
+ KeywordUse: "use",
+ KeywordFfi: "ffi",
+ KeywordDrop: "drop",
+ KeywordAs: "as",
+ KeywordOf: "of",
+ KeywordAnd: "and",
+ KeywordOr: "or",
+ KeywordRef: "ref",
+ KeywordStruct: "struct",
+ KeywordEnum: "enum",
+ KeywordPre: "pre",
+ KeywordPost: "post",
+ KeywordInv: "inv",
+ KeywordIf: "if",
+ KeywordElse: "else",
+ KeywordWhere: "where",
+ KeywordPub: "pub",
+}
+var keywordKinds = map[string]Kind{
+ "ns": KeywordNs,
+ "in": KeywordIn,
+ "from": KeywordFrom,
+ "use": KeywordUse,
+ "ffi": KeywordFfi,
+ "drop": KeywordDrop,
+ "as": KeywordAs,
+ "of": KeywordOf,
+ "and": KeywordAnd,
+ "or": KeywordOr,
+ "ref": KeywordRef,
+ "struct": KeywordStruct,
+ "enum": KeywordEnum,
+ "pre": KeywordPre,
+ "post": KeywordPost,
+ "inv": KeywordInv,
+ "if": KeywordIf,
+ "else": KeywordElse,
+ "where": KeywordWhere,
+ "pub": KeywordPub,
+}
+
type Token struct {
Kind Kind
Value string
@@ -67,7 +138,13 @@ func Lex(filename string, src string) []Token {
i++
col++
}
- res = append(res, Token{Ident, src[start:i], line, startCol})
+
+ ident := src[start:i]
+ kind := Ident
+ if kw, ok := keywordKinds[ident]; ok {
+ kind = kw
+ }
+ res = append(res, Token{kind, src[start:i], line, startCol})
continue
}
if is_digit(c) {
@@ -145,6 +222,14 @@ func Lex(filename string, src string) []Token {
res = append(res, Token{LParen, src[i : i+1], line, col})
case ')':
res = append(res, Token{RParen, src[i : i+1], line, col})
+ case '[':
+ res = append(res, Token{LBracket, src[i : i+1], line, col})
+ case ']':
+ res = append(res, Token{RBracket, src[i : i+1], line, col})
+ case '{':
+ res = append(res, Token{LBrace, src[i : i+1], line, col})
+ case '}':
+ res = append(res, Token{RBrace, src[i : i+1], line, col})
default:
res = append(res, Token{BadToken, src[i : i+1], line, col})
}
@@ -164,6 +249,11 @@ func is_dot(c byte) bool { return c == '.' }
func is_space(c byte) bool { return c == ' ' || c == '\t' || c == '\r' || c == '\n' }
func (k Kind) String() string {
+
+ if text, ok := kindsKeywords[k]; ok {
+ return text
+ }
+
switch k {
case Dot:
return "Dot"
@@ -197,6 +287,14 @@ func (k Kind) String() string {
return "LParen"
case RParen:
return "RParen"
+ case LBrace:
+ return "LBrace"
+ case RBrace:
+ return "RBrace"
+ case LBracket:
+ return "LBracket"
+ case RBracket:
+ return "RBracket"
case EOF:
return "EOF"
case LiteralInt:
@@ -217,6 +315,7 @@ func (k Kind) String() string {
}
func Print_tokens(tokens []Token) {
+
for _, tok := range tokens {
fmt.Printf("%-d:%-2d %-16s %-16q\n", tok.Line, tok.Col, tok.Kind, tok.Value)
}
diff --git a/mtc/parser/parser.go.old b/mtc/p.go.old
diff --git a/mtc/parser/parser.go b/mtc/parser/parser.go
@@ -1,28 +1,189 @@
package parser
-import "mighty/lexer"
+import (
+ "fmt"
+ "mighty/lexer"
+)
-type Node struct {
- kind NodeKind
- Next *Node
+type Pos struct {
Filename string
Line, Col int
}
+type Node interface {
+ anode()
+ Pos() Pos
+}
+
+func (FuncDeclNode) anode() {}
+
+type FuncDeclNode struct {
+}
+
+type Program struct {
+}
+
+func (Program) anode() {}
+
+type P struct {
+ tokens []lexer.Token
+ filename string
+ pos int
+ errs []error
+}
+
+type Parameter struct {
+ Type AnyType
+ Ident lexer.Token
+}
+
+type AnyType interface{ typeRef() }
+
+func (*PointerType) typeRef() {}
+func (*ArrayType) typeRef() {}
+func (*FuncType) typeRef() {}
+func (*NamedType) typeRef() {}
+
+type PointerType struct{ Inner AnyType }
+type ArrayType struct{ Element AnyType }
+
+type FuncType struct {
+ Params []AnyType
+ Return AnyType
+}
+
+type NamedType struct {
+ Name lexer.Token
+ Type AnyType
+}
+
func Parse(filename string, tokens []lexer.Token) Node {
+ return Program{}
if len(tokens) < 1 {
return Node{Filename: filename}
}
+
+ p := P{filename: filename, tokens: tokens}
+ p.parse_root()
+
// make program
- program := Node{Filename: filename}
+ program := Program{}
return program
}
+func (p *P) parse_root() {
+ // namespace, use, decl
+ for p.pos < len(p.tokens) {
+ //t := p.advance()
+ // todo namespace, use
+ p.parse_declaration()
+ }
+}
+
+func (p *P) parse_declaration() {
+ //t := p.peek()
+ // TODO @next check for keyword being pub
+ if p.match(lexer.KeywordPub) {
+ // public declaration
+ p.advance() // consume pub
+ switch p.peek().Kind {
+ case lexer.KeywordStruct:
+ fmt.Println("struct parsing todo")
+ case lexer.KeywordEnum:
+ fmt.Println("enum parsing todo")
+ case lexer.Ident:
+ // function parsing
+ t_type := p.advance()
+ t_label := p.expect(lexer.Ident, "expected Ident for label of function decl")
+ p.expect(lexer.LParen, "expected a ( after function decl label")
+ if !p.check(lexer.RParen) {
+ params := parse_param_list()
+ }
+ default:
+ fmt.Println("undefined parsing")
+ }
+ }
+}
+
+func (p *P) parse_param_list() []Node {
+ var nodes []Node
+ is_array := false
+ for p.pos < len(p.tokens) {
+ switch p.peek().Kind {
+ case lexer.LBracket:
+ p.advance()
+ p.expect(lexer.RBracket, "expect ] in type definition starting with [")
+ is_array = true
+ fallthrough
+ case lexer.Ident:
+ param_type := p.expect(lexer.Ident, "expected type of param")
+ param_name := p.expect(lexer.Ident, "expected name of param")
+ var t AnyType
+ if is_array {
+ t = &ArrayType{}
+ } else {
+ t = &NamedType{}
+ }
+
+ node := Parameter{
+ Ident: param_name,
+ Type: &NamedType{Name: param_type, Type: t},
+ }
+ nodes = append(nodes, node)
+ if !p.match(lexer.Comma) {
+ break
+ }
+ }
+ return nodes
+ }
+}
+
+func (p *P) peek() lexer.Token {
+
+ if p.pos >= len(p.tokens) {
+ return p.tokens[len(p.tokens)-1]
+ }
+
+ return p.tokens[p.pos]
+}
+
+func (p *P) advance() lexer.Token {
+ tok := p.peek()
+ if p.pos < len(p.tokens) {
+ p.pos++
+ }
+ return tok
+}
+
+func (p *P) check(kind lexer.Kind) bool {
+ return p.peek().Kind == kind
+}
+
+func (p *P) match(kind lexer.Kind) bool {
+ if !p.check(kind) {
+ return false
+ }
+ p.advance()
+ return true
+}
+
+func (p *P) expect(kind lexer.Kind, msg string) lexer.Token {
+ if p.check(kind) {
+ return p.advance()
+ }
+
+ p.err(p.peek(), msg)
+ return lexer.Token{Kind: kind}
+}
+
+func (p *P) err(tok lexer.Token, msg string) {
+ p.errs = append(p.errs, fmt.Errorf("%d:%d %s", tok.Line, tok.Col, msg))
+}
+
type NodeKind int
const (
- Program NodeKind = iota
- FuncDecl
+ FuncDecl NodeKind = iota
MethodDecl
StructDecl
Param
@@ -57,9 +218,3 @@ const (
Equality
Inequality
)
-
-func make_program_node(filename string) Node {
- return Node{
- Filename: filename,
- }
-}