mirror of
https://github.com/Fluffy-Bean/GoLox.git
synced 2024-12-26 09:06:05 +00:00
Find keywords
Use runes/chars for characters
This commit is contained in:
parent
175d300e03
commit
a63c07d5bf
122
scanner.go
122
scanner.go
|
@ -31,76 +31,76 @@ func (s *Scanner) ScanTokens() []Token {
|
|||
func (s *Scanner) scanToken() {
|
||||
c := s.advance()
|
||||
switch c {
|
||||
case "(":
|
||||
case '(':
|
||||
s.addToken(LeftBrace)
|
||||
break
|
||||
case ")":
|
||||
case ')':
|
||||
s.addToken(RightBrace)
|
||||
break
|
||||
case "{":
|
||||
case '{':
|
||||
s.addToken(LeftBrace)
|
||||
break
|
||||
case "}":
|
||||
case '}':
|
||||
s.addToken(RightBrace)
|
||||
break
|
||||
case ",":
|
||||
case ',':
|
||||
s.addToken(Comma)
|
||||
break
|
||||
case ".":
|
||||
case '.':
|
||||
s.addToken(Dot)
|
||||
break
|
||||
case "-":
|
||||
case '-':
|
||||
s.addToken(Minus)
|
||||
break
|
||||
case "+":
|
||||
case '+':
|
||||
s.addToken(Plus)
|
||||
break
|
||||
case ";":
|
||||
case ';':
|
||||
s.addToken(Semicolon)
|
||||
break
|
||||
case "*":
|
||||
case '*':
|
||||
s.addToken(Star)
|
||||
break
|
||||
case "!":
|
||||
if s.match("=") {
|
||||
case '!':
|
||||
if s.match('=') {
|
||||
s.addToken(BangEqual)
|
||||
} else {
|
||||
s.addToken(Bang)
|
||||
}
|
||||
break
|
||||
case "=":
|
||||
if s.match("=") {
|
||||
case '=':
|
||||
if s.match('=') {
|
||||
s.addToken(EqualEqual)
|
||||
} else {
|
||||
s.addToken(Equal)
|
||||
}
|
||||
break
|
||||
case "<":
|
||||
if s.match("=") {
|
||||
case '<':
|
||||
if s.match('=') {
|
||||
s.addToken(LessEqual)
|
||||
} else {
|
||||
s.addToken(Less)
|
||||
}
|
||||
break
|
||||
case ">":
|
||||
if s.match("=") {
|
||||
case '>':
|
||||
if s.match('=') {
|
||||
s.addToken(GreaterEqual)
|
||||
} else {
|
||||
s.addToken(Greater)
|
||||
}
|
||||
break
|
||||
case "/":
|
||||
if s.match("/") {
|
||||
for s.peek() != "\n" && !s.isAtEnd() {
|
||||
case '/':
|
||||
if s.match('/') {
|
||||
for s.peek() != '\n' && !s.isAtEnd() {
|
||||
s.advance()
|
||||
}
|
||||
} else {
|
||||
s.addToken(Slash)
|
||||
}
|
||||
break
|
||||
case "\"":
|
||||
for s.peek() != "\"" && !s.isAtEnd() {
|
||||
if s.peek() == "\n" {
|
||||
case '"':
|
||||
for s.peek() != '"' && !s.isAtEnd() {
|
||||
if s.peek() == '\n' {
|
||||
s.line += 1
|
||||
}
|
||||
s.advance()
|
||||
|
@ -115,12 +115,11 @@ func (s *Scanner) scanToken() {
|
|||
s.addTokenWithLiteral(String, s.source[s.start+1:s.current-1]) // +- to remove ""
|
||||
|
||||
break
|
||||
case " ":
|
||||
case "\t":
|
||||
case "\r":
|
||||
// ignore whitespace
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
break
|
||||
case "\n":
|
||||
case '\n':
|
||||
s.line += 1
|
||||
break
|
||||
default:
|
||||
|
@ -128,10 +127,8 @@ func (s *Scanner) scanToken() {
|
|||
for s.isDigit(s.peek()) {
|
||||
s.advance()
|
||||
}
|
||||
|
||||
if s.peek() == "." && s.isDigit(s.peekAfter()) {
|
||||
if s.peek() == '.' && s.isDigit(s.peekAfter()) {
|
||||
s.advance() // eated .
|
||||
|
||||
for s.isDigit(s.peek()) {
|
||||
s.advance()
|
||||
}
|
||||
|
@ -143,6 +140,19 @@ func (s *Scanner) scanToken() {
|
|||
}
|
||||
|
||||
s.addTokenWithLiteral(Number, fmt.Sprintf("%f", number)) // convert back to string, lol
|
||||
} else if s.isAlpha(c) {
|
||||
for s.isAlpha(s.peek()) {
|
||||
s.advance()
|
||||
}
|
||||
|
||||
keyword := s.source[s.start:s.current]
|
||||
|
||||
val, ok := Tokens[keyword]
|
||||
if !ok {
|
||||
val = Identifier
|
||||
}
|
||||
|
||||
s.addToken(val)
|
||||
} else {
|
||||
fuck(s.line, "Unexpected Character")
|
||||
}
|
||||
|
@ -150,45 +160,51 @@ func (s *Scanner) scanToken() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Scanner) advance() string {
|
||||
c := string(s.source[s.current])
|
||||
func (s *Scanner) advance() rune {
|
||||
c := rune(s.source[s.current])
|
||||
s.current += 1
|
||||
return c
|
||||
}
|
||||
|
||||
func (s *Scanner) peek() string {
|
||||
func (s *Scanner) peek() rune {
|
||||
if s.isAtEnd() {
|
||||
return ""
|
||||
return '0'
|
||||
}
|
||||
return string(s.source[s.current])
|
||||
return rune(s.source[s.current])
|
||||
}
|
||||
|
||||
func (s *Scanner) peekAfter() string {
|
||||
func (s *Scanner) peekAfter() rune {
|
||||
if s.current+1 >= len(s.source) {
|
||||
return ""
|
||||
return '0'
|
||||
}
|
||||
return string(s.source[s.current+1])
|
||||
return rune(s.source[s.current+1])
|
||||
}
|
||||
|
||||
func (s *Scanner) match(expected string) bool {
|
||||
func (s *Scanner) match(c rune) bool {
|
||||
if s.isAtEnd() {
|
||||
return false
|
||||
}
|
||||
if string(s.source[s.current]) != expected {
|
||||
if rune(s.source[s.current]) != c {
|
||||
return false
|
||||
}
|
||||
s.current += 1
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Scanner) isDigit(val string) bool {
|
||||
// Lazy way of doing thia, Atoi could work, but unsure if it has any funkiness to it.....
|
||||
for _, number := range "0123456789" {
|
||||
if val == string(number) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
func (s *Scanner) isDigit(c rune) bool {
|
||||
return c >= '0' && c <= '9'
|
||||
}
|
||||
|
||||
func (s *Scanner) isAlpha(c rune) bool {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
|
||||
}
|
||||
|
||||
func (s *Scanner) isAlphaNumeric(c rune) bool {
|
||||
return s.isAlpha(c) || s.isDigit(c)
|
||||
}
|
||||
|
||||
func (s *Scanner) isAtEnd() bool {
|
||||
return s.current >= len(s.source)
|
||||
}
|
||||
|
||||
func (s *Scanner) addToken(token int) {
|
||||
|
@ -198,8 +214,6 @@ func (s *Scanner) addToken(token int) {
|
|||
Literal: "",
|
||||
Line: s.line,
|
||||
})
|
||||
//fmt.Printf("[%d %d %d] ", s.line, s.current, s.start)
|
||||
//fmt.Println(s.tokens[len(s.tokens)-1])
|
||||
}
|
||||
|
||||
func (s *Scanner) addTokenWithLiteral(token int, value string) {
|
||||
|
@ -211,10 +225,6 @@ func (s *Scanner) addTokenWithLiteral(token int, value string) {
|
|||
})
|
||||
}
|
||||
|
||||
func (s *Scanner) isAtEnd() bool {
|
||||
return s.current >= len(s.source)
|
||||
}
|
||||
|
||||
func NewScanner(source string) *Scanner {
|
||||
return &Scanner{
|
||||
source: source,
|
||||
|
|
12
scripts/function.lox
Normal file
12
scripts/function.lox
Normal file
|
@ -0,0 +1,12 @@
|
|||
fun main() {
|
||||
example("world")
|
||||
}
|
||||
|
||||
fun example(name) {
|
||||
print "Hello, "
|
||||
print name
|
||||
print "!\n"
|
||||
}
|
||||
|
||||
// Start program
|
||||
main()
|
21
tokens.go
21
tokens.go
|
@ -41,7 +41,7 @@ const (
|
|||
Fun
|
||||
For
|
||||
If
|
||||
Nah
|
||||
Null
|
||||
Or
|
||||
Print
|
||||
Return
|
||||
|
@ -54,6 +54,25 @@ const (
|
|||
EOF
|
||||
)
|
||||
|
||||
var Tokens = map[string]int{
|
||||
"and": And,
|
||||
"class": Class,
|
||||
"else": Else,
|
||||
"false": False,
|
||||
"fun": Fun,
|
||||
"for": For,
|
||||
"if": If,
|
||||
"null": Null,
|
||||
"or": Or,
|
||||
"print": Print,
|
||||
"return": Return,
|
||||
"super": Super,
|
||||
"this": This,
|
||||
"true": True,
|
||||
"var": Var,
|
||||
"while": While,
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Type int
|
||||
Lexeme string
|
||||
|
|
Loading…
Reference in a new issue