2022-08-10 09:28:29 -06:00
|
|
|
package lexer
|
|
|
|
|
|
|
|
import "testing"
|
2022-08-29 23:11:10 -06:00
|
|
|
import "git.tebibyte.media/arf/arf/file"
|
|
|
|
import "git.tebibyte.media/arf/arf/types"
|
|
|
|
import "git.tebibyte.media/arf/arf/infoerr"
|
2022-08-10 09:28:29 -06:00
|
|
|
|
2022-08-18 09:14:42 -06:00
|
|
|
func quickToken (width int, kind TokenKind, value any) (token Token) {
|
|
|
|
token.location.SetWidth(width)
|
|
|
|
token.kind = kind
|
|
|
|
token.value = value
|
|
|
|
return
|
2022-08-18 09:02:49 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func checkTokenSlice (filePath string, test *testing.T, correct ...Token) {
|
2022-08-17 23:25:02 -06:00
|
|
|
test.Log("checking lexer results for", filePath)
|
2022-08-11 03:23:06 -06:00
|
|
|
file, err := file.Open(filePath)
|
2022-08-10 09:28:29 -06:00
|
|
|
if err != nil {
|
|
|
|
test.Log(err)
|
|
|
|
test.Fail()
|
2022-08-10 10:58:47 -06:00
|
|
|
return
|
2022-08-10 09:28:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
tokens, err := Tokenize(file)
|
2022-08-10 13:02:08 -06:00
|
|
|
|
|
|
|
// print all tokens
|
2022-08-11 02:58:45 -06:00
|
|
|
for index, token := range tokens {
|
|
|
|
test.Log(index, "\tgot token:", token.Describe())
|
2022-08-10 13:02:08 -06:00
|
|
|
}
|
|
|
|
|
2022-08-11 01:47:51 -06:00
|
|
|
if err != nil {
|
|
|
|
test.Log("returned error:")
|
|
|
|
test.Log(err.Error())
|
2022-08-10 09:28:29 -06:00
|
|
|
test.Fail()
|
2022-08-10 10:58:47 -06:00
|
|
|
return
|
2022-08-10 09:28:29 -06:00
|
|
|
}
|
|
|
|
|
2022-08-11 03:23:06 -06:00
|
|
|
if len(tokens) != len(correct) {
|
|
|
|
test.Log("lexed", len(tokens), "tokens, want", len(correct))
|
|
|
|
test.Fail()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
test.Log("token slice length match", len(tokens), "=", len(correct))
|
|
|
|
|
|
|
|
for index, token := range tokens {
|
2022-08-18 09:14:42 -06:00
|
|
|
if token.location.Width() != correct[index].location.Width() {
|
|
|
|
test.Log("token", index, "has bad width")
|
|
|
|
test.Log (
|
|
|
|
"have", token.location.Width(),
|
|
|
|
"want", correct[index].location.Width())
|
|
|
|
test.Fail()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-08-11 03:23:06 -06:00
|
|
|
if !token.Equals(correct[index]) {
|
|
|
|
test.Log("token", index, "not equal")
|
|
|
|
test.Log (
|
|
|
|
"have", token.Describe(),
|
|
|
|
"want", correct[index].Describe())
|
|
|
|
test.Fail()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
test.Log("token slice content match")
|
|
|
|
}
|
|
|
|
|
2022-08-17 23:25:02 -06:00
|
|
|
func compareErr (
|
|
|
|
filePath string,
|
|
|
|
correctKind infoerr.ErrorKind,
|
|
|
|
correctMessage string,
|
|
|
|
correctRow int,
|
|
|
|
correctColumn int,
|
|
|
|
correctWidth int,
|
|
|
|
test *testing.T,
|
|
|
|
) {
|
|
|
|
test.Log("testing errors in", filePath)
|
|
|
|
file, err := file.Open(filePath)
|
|
|
|
if err != nil {
|
|
|
|
test.Log(err)
|
|
|
|
test.Fail()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = Tokenize(file)
|
|
|
|
check := err.(infoerr.Error)
|
|
|
|
|
2022-08-17 23:47:35 -06:00
|
|
|
test.Log("error that was recieved:")
|
|
|
|
test.Log(check)
|
|
|
|
|
2022-08-17 23:25:02 -06:00
|
|
|
if check.Kind() != correctKind {
|
|
|
|
test.Log("mismatched error kind")
|
|
|
|
test.Log("- want:", correctKind)
|
|
|
|
test.Log("- have:", check.Kind())
|
|
|
|
test.Fail()
|
|
|
|
}
|
|
|
|
|
|
|
|
if check.Message() != correctMessage {
|
|
|
|
test.Log("mismatched error message")
|
|
|
|
test.Log("- want:", correctMessage)
|
|
|
|
test.Log("- have:", check.Message())
|
|
|
|
test.Fail()
|
|
|
|
}
|
|
|
|
|
|
|
|
if check.Row() != correctRow {
|
|
|
|
test.Log("mismatched error row")
|
|
|
|
test.Log("- want:", correctRow)
|
|
|
|
test.Log("- have:", check.Row())
|
|
|
|
test.Fail()
|
|
|
|
}
|
|
|
|
|
|
|
|
if check.Column() != correctColumn {
|
|
|
|
test.Log("mismatched error column")
|
|
|
|
test.Log("- want:", correctColumn)
|
|
|
|
test.Log("- have:", check.Column())
|
|
|
|
test.Fail()
|
|
|
|
}
|
|
|
|
|
|
|
|
if check.Width() != correctWidth {
|
|
|
|
test.Log("mismatched error width")
|
|
|
|
test.Log("- want:", check.Width())
|
|
|
|
test.Log("- have:", correctWidth)
|
|
|
|
test.Fail()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-11 03:23:06 -06:00
|
|
|
func TestTokenizeAll (test *testing.T) {
|
2022-08-18 09:02:49 -06:00
|
|
|
checkTokenSlice("../tests/lexer/all.arf", test,
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(3, TokenKindSeparator, nil),
|
2022-08-18 10:09:17 -06:00
|
|
|
quickToken(2, TokenKindPermission, types.PermissionReadWrite),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(2, TokenKindReturnDirection, nil),
|
|
|
|
quickToken(10, TokenKindInt, int64(-349820394)),
|
|
|
|
quickToken(9, TokenKindUInt, uint64(932748397)),
|
|
|
|
quickToken(12, TokenKindFloat, 239485.37520),
|
|
|
|
quickToken(16, TokenKindString, "hello world!\n"),
|
|
|
|
quickToken(3, TokenKindRune, 'E'),
|
|
|
|
quickToken(10, TokenKindName, "helloWorld"),
|
|
|
|
quickToken(1, TokenKindColon, nil),
|
|
|
|
quickToken(1, TokenKindDot, nil),
|
|
|
|
quickToken(1, TokenKindComma, nil),
|
|
|
|
quickToken(2, TokenKindElipsis, nil),
|
|
|
|
quickToken(1, TokenKindLBracket, nil),
|
|
|
|
quickToken(1, TokenKindRBracket, nil),
|
|
|
|
quickToken(1, TokenKindLBrace, nil),
|
|
|
|
quickToken(1, TokenKindRBrace, nil),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(1, TokenKindPlus, nil),
|
|
|
|
quickToken(1, TokenKindMinus, nil),
|
|
|
|
quickToken(2, TokenKindIncrement, nil),
|
|
|
|
quickToken(2, TokenKindDecrement, nil),
|
|
|
|
quickToken(1, TokenKindAsterisk, nil),
|
|
|
|
quickToken(1, TokenKindSlash, nil),
|
|
|
|
quickToken(1, TokenKindAt, nil),
|
|
|
|
quickToken(1, TokenKindExclamation, nil),
|
|
|
|
quickToken(1, TokenKindPercent, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(2, TokenKindPercentAssignment, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(1, TokenKindTilde, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(2, TokenKindTildeAssignment, nil),
|
2022-09-03 18:23:27 -06:00
|
|
|
quickToken(1, TokenKindAssignment, nil),
|
|
|
|
quickToken(2, TokenKindEqualTo, nil),
|
2022-08-24 22:05:40 -06:00
|
|
|
quickToken(2, TokenKindNotEqualTo, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(1, TokenKindLessThan, nil),
|
2022-08-24 22:05:40 -06:00
|
|
|
quickToken(2, TokenKindLessThanEqualTo, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(2, TokenKindLShift, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(3, TokenKindLShiftAssignment, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(1, TokenKindGreaterThan, nil),
|
2022-08-24 22:05:40 -06:00
|
|
|
quickToken(2, TokenKindGreaterThanEqualTo, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(2, TokenKindRShift, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(3, TokenKindRShiftAssignment, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(1, TokenKindBinaryOr, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(2, TokenKindBinaryOrAssignment, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(2, TokenKindLogicalOr, nil),
|
|
|
|
quickToken(1, TokenKindBinaryAnd, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(2, TokenKindBinaryAndAssignment, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(2, TokenKindLogicalAnd, nil),
|
2022-08-25 21:17:42 -06:00
|
|
|
quickToken(1, TokenKindBinaryXor, nil),
|
|
|
|
quickToken(2, TokenKindBinaryXorAssignment, nil),
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(1, TokenKindNewline, nil),
|
2022-08-18 09:02:49 -06:00
|
|
|
)
|
2022-08-11 03:23:06 -06:00
|
|
|
}
|
2022-08-10 09:28:29 -06:00
|
|
|
|
2022-08-11 03:23:06 -06:00
|
|
|
func TestTokenizeNumbers (test *testing.T) {
|
2022-08-18 09:02:49 -06:00
|
|
|
checkTokenSlice("../tests/lexer/numbers.arf", test,
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(1, TokenKindUInt, uint64(0)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(1, TokenKindUInt, uint64(8)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(8, TokenKindUInt, uint64(83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(29, TokenKindUInt, uint64(83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(9, TokenKindUInt, uint64(83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(10, TokenKindUInt, uint64(83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
2022-08-11 03:23:06 -06:00
|
|
|
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(9, TokenKindInt, int64(-83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(30, TokenKindInt, int64(-83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(10, TokenKindInt, int64(-83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(11, TokenKindInt, int64(-83628266)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
2022-08-11 03:23:06 -06:00
|
|
|
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(8, TokenKindFloat, float64(0.123478)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(8, TokenKindFloat, float64(234.3095)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(6, TokenKindFloat, float64(-2.312)),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
2022-08-18 09:02:49 -06:00
|
|
|
)
|
2022-08-10 09:28:29 -06:00
|
|
|
}
|
2022-08-11 11:12:41 -06:00
|
|
|
|
|
|
|
func TestTokenizeText (test *testing.T) {
|
2022-08-18 09:02:49 -06:00
|
|
|
checkTokenSlice("../tests/lexer/text.arf", test,
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(34, TokenKindString, "hello world!\a\b\f\n\r\t\v'\"\\"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(4, TokenKindRune, '\a'),
|
|
|
|
quickToken(4, TokenKindRune, '\b'),
|
|
|
|
quickToken(4, TokenKindRune, '\f'),
|
|
|
|
quickToken(4, TokenKindRune, '\n'),
|
|
|
|
quickToken(4, TokenKindRune, '\r'),
|
|
|
|
quickToken(4, TokenKindRune, '\t'),
|
|
|
|
quickToken(4, TokenKindRune, '\v'),
|
|
|
|
quickToken(4, TokenKindRune, '\''),
|
|
|
|
quickToken(4, TokenKindRune, '"' ),
|
|
|
|
quickToken(4, TokenKindRune, '\\'),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(35, TokenKindString, "hello world \x40\u0040\U00000040!"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
2022-08-18 09:02:49 -06:00
|
|
|
)
|
2022-08-11 11:12:41 -06:00
|
|
|
}
|
2022-08-11 11:47:50 -06:00
|
|
|
|
|
|
|
func TestTokenizeIndent (test *testing.T) {
|
2022-08-18 09:02:49 -06:00
|
|
|
checkTokenSlice("../tests/lexer/indent.arf", test,
|
2022-08-18 09:14:42 -06:00
|
|
|
quickToken(5, TokenKindName, "line1"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(1, TokenKindIndent, 1),
|
|
|
|
quickToken(5, TokenKindName, "line2"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(4, TokenKindIndent, 4),
|
|
|
|
quickToken(5, TokenKindName, "line3"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(5, TokenKindName, "line4"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
|
|
|
quickToken(2, TokenKindIndent, 2),
|
|
|
|
quickToken(5, TokenKindName, "line5"),
|
|
|
|
quickToken(1, TokenKindNewline, nil),
|
2022-08-18 09:02:49 -06:00
|
|
|
)
|
2022-08-11 11:47:50 -06:00
|
|
|
}
|
2022-08-17 23:25:02 -06:00
|
|
|
|
|
|
|
func TestTokenizeErr (test *testing.T) {
|
|
|
|
compareErr (
|
2022-08-17 23:47:35 -06:00
|
|
|
"../tests/lexer/error/unexpectedSymbol.arf",
|
2022-08-17 23:25:02 -06:00
|
|
|
infoerr.ErrorKindError,
|
|
|
|
"unexpected symbol character ;",
|
2022-08-17 23:47:35 -06:00
|
|
|
1, 5, 1,
|
|
|
|
test)
|
|
|
|
|
|
|
|
compareErr (
|
|
|
|
"../tests/lexer/error/excessDataRune.arf",
|
|
|
|
infoerr.ErrorKindError,
|
|
|
|
"excess data in rune literal",
|
2022-08-18 00:06:00 -06:00
|
|
|
1, 1, 7,
|
2022-08-17 23:47:35 -06:00
|
|
|
test)
|
|
|
|
|
|
|
|
compareErr (
|
|
|
|
"../tests/lexer/error/unknownEscape.arf",
|
|
|
|
infoerr.ErrorKindError,
|
|
|
|
"unknown escape character g",
|
2022-08-18 00:06:00 -06:00
|
|
|
1, 2, 1,
|
2022-08-17 23:25:02 -06:00
|
|
|
test)
|
|
|
|
}
|