- Compiler: PP → Lexer → Parser → Analyzer → Gengo pipeline - Parser: 232/236 (98%) Harbour compatibility, registry-based dispatch - RTL: 351 Harbour-compatible functions - RDD: DBF/NTX/CDX engines with Rushmore bitmap optimization - Go Interop: IMPORT + pkg.Func() + obj:Method() with FastPath (15M calls/sec) - HB_FUNC API: Full Harbour C API compatible Go bridge - Concurrency: SPAWN/LAUNCH/GOROUTINE, <-, WATCH, PARALLEL FOR, ASYNC/AWAIT - Extensions: Multi-return, DEFER, Slice, f-string, Nil-safe ?:, CONST - Macro Compiler: Runtime AST parsing and evaluation - Debugger: TUI debugger with source display, breakpoints, stepping - FRB: Native + Pcode dual mode runtime binary - Tests: 13 packages ALL PASS Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
114 lines
2.4 KiB
Go
114 lines
2.4 KiB
Go
// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
|
|
// All rights reserved.
|
|
|
|
package token
|
|
|
|
import "testing"
|
|
|
|
func TestLookupKeyword(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
want Kind
|
|
}{
|
|
{"FUNCTION", FUNCTION_KW},
|
|
{"function", FUNCTION_KW},
|
|
{"Function", FUNCTION_KW},
|
|
{"FuNcTiOn", FUNCTION_KW},
|
|
{"IF", IF},
|
|
{"if", IF},
|
|
{"LOCAL", LOCAL},
|
|
{"RETURN", RETURN},
|
|
{"USE", USE},
|
|
{"SEEK", SEEK},
|
|
{"CLASS", CLASS},
|
|
{"IMPORT", IMPORT},
|
|
{"NIL", NIL_LIT},
|
|
// Aliases
|
|
{"FUNC", FUNCTION_KW},
|
|
{"PROC", PROCEDURE},
|
|
// Not keywords
|
|
{"myVar", IDENT},
|
|
{"foo", IDENT},
|
|
{"x", IDENT},
|
|
}
|
|
for _, tt := range tests {
|
|
got := LookupKeyword(tt.input)
|
|
if got != tt.want {
|
|
t.Errorf("LookupKeyword(%q) = %v, want %v", tt.input, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetBinaryPrecedence(t *testing.T) {
|
|
tests := []struct {
|
|
kind Kind
|
|
want Precedence
|
|
}{
|
|
{ASSIGN, PrecAssign},
|
|
{OR, PrecOr},
|
|
{AND, PrecAnd},
|
|
{EQ, PrecComparison},
|
|
{EXEQ, PrecComparison},
|
|
{NEQ, PrecComparison},
|
|
{LT, PrecComparison},
|
|
{GT, PrecComparison},
|
|
{LTE, PrecComparison},
|
|
{GTE, PrecComparison},
|
|
{DOLLAR, PrecComparison},
|
|
{PLUS, PrecAddition},
|
|
{MINUS, PrecAddition},
|
|
{STAR, PrecMultiply},
|
|
{SLASH, PrecMultiply},
|
|
{PERCENT, PrecMultiply},
|
|
{POWER, PrecPower},
|
|
// Not binary
|
|
{IDENT, PrecNone},
|
|
{LPAREN, PrecNone},
|
|
{EOF, PrecNone},
|
|
}
|
|
for _, tt := range tests {
|
|
got := GetBinaryPrecedence(tt.kind)
|
|
if got != tt.want {
|
|
t.Errorf("GetBinaryPrecedence(%v) = %v, want %v", tt.kind, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsRightAssociative(t *testing.T) {
|
|
if !IsRightAssociative(POWER) {
|
|
t.Error("** should be right associative")
|
|
}
|
|
if !IsRightAssociative(ASSIGN) {
|
|
t.Error(":= should be right associative")
|
|
}
|
|
if IsRightAssociative(PLUS) {
|
|
t.Error("+ should NOT be right associative")
|
|
}
|
|
}
|
|
|
|
func TestToUpper(t *testing.T) {
|
|
tests := []struct{ in, want string }{
|
|
{"abc", "ABC"},
|
|
{"ABC", "ABC"},
|
|
{"aBc", "ABC"},
|
|
{"", ""},
|
|
{"123", "123"},
|
|
{"hello_world", "HELLO_WORLD"},
|
|
}
|
|
for _, tt := range tests {
|
|
got := toUpper(tt.in)
|
|
if got != tt.want {
|
|
t.Errorf("toUpper(%q) = %q, want %q", tt.in, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestKindString(t *testing.T) {
|
|
if PLUS.String() != "+" {
|
|
t.Errorf("PLUS.String() = %q, want %q", PLUS.String(), "+")
|
|
}
|
|
if FUNCTION_KW.String() != "FUNCTION" {
|
|
t.Errorf("FUNCTION_KW.String() = %q", FUNCTION_KW.String())
|
|
}
|
|
}
|