feat: add lexer
This commit is contained in:
parent
8129c36220
commit
40cafa53f0
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@ -0,0 +1,12 @@
|
||||
ARG GO_VERSION=1.21.1
|
||||
|
||||
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS base
|
||||
WORKDIR /src
|
||||
# RUN --mount=type=bind,target=go.mod \
|
||||
# --mount=type=bind,target=go.sum \
|
||||
# go mod download
|
||||
|
||||
FROM base as tests
|
||||
WORKDIR /src
|
||||
RUN --mount=type=bind,target=. \
|
||||
go test ./...
|
15
compose.yaml
Normal file
15
compose.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
base:
|
||||
build:
|
||||
target: base
|
||||
volumes:
|
||||
- .:/src
|
||||
working_dir: /src
|
||||
|
||||
format:
|
||||
extends:
|
||||
service: base
|
||||
entrypoint: "gofmt -w *.go"
|
60
lexer/lexer.go
Normal file
60
lexer/lexer.go
Normal file
@ -0,0 +1,60 @@
|
||||
package lexer
|
||||
|
||||
import "git.cybercyst.me/monkeylang/token"
|
||||
|
||||
type Lexer struct {
|
||||
input string
|
||||
position int
|
||||
readPosition int
|
||||
ch byte
|
||||
}
|
||||
|
||||
func New(input string) *Lexer {
|
||||
l := &Lexer{input: input}
|
||||
l.readChar()
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *Lexer) readChar() {
|
||||
if l.readPosition >= len(l.input) {
|
||||
l.ch = 0
|
||||
} else {
|
||||
l.ch = l.input[l.readPosition]
|
||||
}
|
||||
|
||||
l.position = l.readPosition
|
||||
l.readPosition += 1
|
||||
}
|
||||
|
||||
func (l *Lexer) NextToken() token.Token {
|
||||
var tok token.Token
|
||||
|
||||
switch l.ch {
|
||||
case '=':
|
||||
tok = newToken(token.ASSIGN, l.ch)
|
||||
case ';':
|
||||
tok = newToken(token.SEMICOLON, l.ch)
|
||||
case '(':
|
||||
tok = newToken(token.LPAREN, l.ch)
|
||||
case ')':
|
||||
tok = newToken(token.RPAREN, l.ch)
|
||||
case ',':
|
||||
tok = newToken(token.COMMA, l.ch)
|
||||
case '+':
|
||||
tok = newToken(token.PLUS, l.ch)
|
||||
case '{':
|
||||
tok = newToken(token.LBRACE, l.ch)
|
||||
case '}':
|
||||
tok = newToken(token.RBRACE, l.ch)
|
||||
case 0:
|
||||
tok.Literal = ""
|
||||
tok.Type = token.EOF
|
||||
}
|
||||
|
||||
l.readChar()
|
||||
return tok
|
||||
}
|
||||
|
||||
func newToken(tokenType token.TokenType, ch byte) token.Token {
|
||||
return token.Token{Type: tokenType, Literal: string(ch)}
|
||||
}
|
40
lexer/lexer_test.go
Normal file
40
lexer/lexer_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
package lexer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.cybercyst.me/monkeylang/token"
|
||||
)
|
||||
|
||||
func TextNextToken(t *testing.T) {
|
||||
input := `=+(){},;`
|
||||
|
||||
tests := []struct {
|
||||
expectedType token.TokenType
|
||||
expectedLiteral string
|
||||
}{
|
||||
{token.ASSIGN, "="},
|
||||
{token.PLUS, "+"},
|
||||
{token.LPAREN, "("},
|
||||
{token.RPAREN, ")"},
|
||||
{token.LBRACE, "{"},
|
||||
{token.RBRACE, "}"},
|
||||
{token.COMMA, ","},
|
||||
{token.SEMICOLON, ";"},
|
||||
}
|
||||
|
||||
l := New(input)
|
||||
|
||||
for i, tt := range tests {
|
||||
tok := l.NextToken()
|
||||
if tok.Type != tt.expectedType {
|
||||
t.Fatalf("tests[%d] - tokentype wrong. expected=%q, got=%q",
|
||||
i, tt.expectedType, tok.Type)
|
||||
}
|
||||
|
||||
if tok.Literal != tt.expectedLiteral {
|
||||
t.Fatalf("tests[%d] - literal wrong. expected=%q, got=%q",
|
||||
i, tt.expectedLiteral, tok.Literal)
|
||||
}
|
||||
}
|
||||
}
|
7
main.go
Normal file
7
main.go
Normal file
@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello, World!")
|
||||
}
|
31
token/token.go
Normal file
31
token/token.go
Normal file
@ -0,0 +1,31 @@
|
||||
package token
|
||||
|
||||
type TokenType string
|
||||
|
||||
type Token struct {
|
||||
Type TokenType
|
||||
Literal string
|
||||
}
|
||||
|
||||
const (
|
||||
ILLEGAL = "ILLEGAL"
|
||||
EOF = "EOF" // Identifiers + literals
|
||||
IDENT = "IDENT" // add, foobar, x, y, ...
|
||||
INT = "INT" // 1343456
|
||||
|
||||
// Operators
|
||||
ASSIGN = "="
|
||||
PLUS = "+"
|
||||
|
||||
// Delimiters
|
||||
COMMA = ","
|
||||
SEMICOLON = ";"
|
||||
LPAREN = "("
|
||||
RPAREN = ")"
|
||||
LBRACE = "{"
|
||||
RBRACE = "}"
|
||||
|
||||
// Keywords
|
||||
FUNCTION = "FUNCTION"
|
||||
LET = "LET"
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user