From dbc28fd8fb2d614f3449764c81226a108bf02e3b Mon Sep 17 00:00:00 2001 From: Adam Eury Date: Mon, 15 Jan 2024 18:26:12 -0500 Subject: [PATCH] Add string literal support to the lexer. --- examples/print.g | 16 ++++++++++++++++ lexer/lexer.go | 16 ++++++++++++++++ lexer/lexer_test.go | 15 +++++++++++---- token/token.go | 1 + 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 examples/print.g diff --git a/examples/print.g b/examples/print.g new file mode 100644 index 0000000..5bd9efa --- /dev/null +++ b/examples/print.g @@ -0,0 +1,16 @@ +@data msg "hello world" + +.run +SETX msg ; set X register to the address of msg +JUMP print + +.done +HALT + +.print +MOVX A ; move the value of address in X to A +JAEZ done ; jump to label 'done' if A = 0 +OUTA ; print A +INCX ; increment address stored in X +JUMP print ; jump back to the start of .print to print the next character + diff --git a/lexer/lexer.go b/lexer/lexer.go index e24e0c0..b6fc657 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -40,6 +40,9 @@ func (l *Lexer) NextToken() token.Token { case l.ch == '\'': char := l.readCharacter() return l.newToken(token.CHAR, char) + case l.ch == '"': + str := l.readString() + return l.newToken(token.STRING, str) case l.ch == 0: return l.newToken(token.EOF, "") case unicode.IsDigit(l.ch): @@ -75,6 +78,19 @@ func (l *Lexer) readUntil(r rune) string { return l.input[start:l.position] } +func (l *Lexer) readString() string { + position := l.position + 1 + for { + l.readChar() + if l.ch == '"' || l.ch == 0 { + break + } + } + // consume closing quote + l.readChar() + return l.input[position : l.position-1] +} + func (l *Lexer) readCharacter() string { start := l.position l.readChar() diff --git a/lexer/lexer_test.go b/lexer/lexer_test.go index 21d1d11..c2f9d80 100644 --- a/lexer/lexer_test.go +++ b/lexer/lexer_test.go @@ -43,8 +43,11 @@ DECA PSHA POPA MOVA X +MOVA Y OUTA -HALT` +HALT +"test" +""` tests := []struct { expectedType token.TokenType expectedLiteral string @@ -69,9 +72,13 @@ HALT` {token.OPCODE, "POPA", 20}, {token.OPCODE, "MOVA", 21}, {token.REGISTER, "X", 21}, - {token.OPCODE, "OUTA", 22}, - {token.OPCODE, "HALT", 23}, - {token.EOF, "", 23}, + {token.OPCODE, "MOVA", 22}, + {token.REGISTER, "Y", 22}, + {token.OPCODE, "OUTA", 23}, + {token.OPCODE, "HALT", 24}, + {token.STRING, "test", 25}, + {token.STRING, "", 26}, + {token.EOF, "", 26}, } l := newLexerFromString(input) diff --git a/token/token.go b/token/token.go index 8ca1ea2..8d8dd35 100644 --- a/token/token.go +++ b/token/token.go @@ -11,6 +11,7 @@ const ( IDENT = "IDENT" INT = "INT" CHAR = "CHAR" + STRING = "STRING" ) var registers = map[string]TokenType{