123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package tengo_test
- import (
- "testing"
- "github.com/d5/tengo/v2"
- "github.com/d5/tengo/v2/require"
- )
- func TestSymbolTable(t *testing.T) {
- /*
- GLOBAL
- [0] a
- [1] b
- LOCAL 1
- [0] d
- LOCAL 2
- [0] e
- [1] f
- LOCAL 2 BLOCK 1
- [2] g
- [3] h
- LOCAL 2 BLOCK 2
- [2] i
- [3] j
- [4] k
- LOCAL 1 BLOCK 1
- [1] l
- [2] m
- [3] n
- [4] o
- [5] p
- LOCAL 3
- [0] q
- [1] r
- */
- global := symbolTable()
- require.Equal(t, globalSymbol("a", 0), global.Define("a"))
- require.Equal(t, globalSymbol("b", 1), global.Define("b"))
- local1 := global.Fork(false)
- require.Equal(t, localSymbol("d", 0), local1.Define("d"))
- local1Block1 := local1.Fork(true)
- require.Equal(t, localSymbol("l", 1), local1Block1.Define("l"))
- require.Equal(t, localSymbol("m", 2), local1Block1.Define("m"))
- require.Equal(t, localSymbol("n", 3), local1Block1.Define("n"))
- require.Equal(t, localSymbol("o", 4), local1Block1.Define("o"))
- require.Equal(t, localSymbol("p", 5), local1Block1.Define("p"))
- local2 := local1.Fork(false)
- require.Equal(t, localSymbol("e", 0), local2.Define("e"))
- require.Equal(t, localSymbol("f", 1), local2.Define("f"))
- local2Block1 := local2.Fork(true)
- require.Equal(t, localSymbol("g", 2), local2Block1.Define("g"))
- require.Equal(t, localSymbol("h", 3), local2Block1.Define("h"))
- local2Block2 := local2.Fork(true)
- require.Equal(t, localSymbol("i", 2), local2Block2.Define("i"))
- require.Equal(t, localSymbol("j", 3), local2Block2.Define("j"))
- require.Equal(t, localSymbol("k", 4), local2Block2.Define("k"))
- local3 := local1Block1.Fork(false)
- require.Equal(t, localSymbol("q", 0), local3.Define("q"))
- require.Equal(t, localSymbol("r", 1), local3.Define("r"))
- require.Equal(t, 2, global.MaxSymbols())
- require.Equal(t, 6, local1.MaxSymbols())
- require.Equal(t, 6, local1Block1.MaxSymbols())
- require.Equal(t, 5, local2.MaxSymbols())
- require.Equal(t, 4, local2Block1.MaxSymbols())
- require.Equal(t, 5, local2Block2.MaxSymbols())
- require.Equal(t, 2, local3.MaxSymbols())
- resolveExpect(t, global, "a", globalSymbol("a", 0), 0)
- resolveExpect(t, local1, "d", localSymbol("d", 0), 0)
- resolveExpect(t, local1, "a", globalSymbol("a", 0), 1)
- resolveExpect(t, local3, "a", globalSymbol("a", 0), 3)
- resolveExpect(t, local3, "d", freeSymbol("d", 0), 2)
- resolveExpect(t, local3, "r", localSymbol("r", 1), 0)
- resolveExpect(t, local2Block2, "k", localSymbol("k", 4), 0)
- resolveExpect(t, local2Block2, "e", localSymbol("e", 0), 1)
- resolveExpect(t, local2Block2, "b", globalSymbol("b", 1), 3)
- }
- func symbol(
- name string,
- scope tengo.SymbolScope,
- index int,
- ) *tengo.Symbol {
- return &tengo.Symbol{
- Name: name,
- Scope: scope,
- Index: index,
- }
- }
- func globalSymbol(name string, index int) *tengo.Symbol {
- return symbol(name, tengo.ScopeGlobal, index)
- }
- func localSymbol(name string, index int) *tengo.Symbol {
- return symbol(name, tengo.ScopeLocal, index)
- }
- func freeSymbol(name string, index int) *tengo.Symbol {
- return symbol(name, tengo.ScopeFree, index)
- }
- func symbolTable() *tengo.SymbolTable {
- return tengo.NewSymbolTable()
- }
- func resolveExpect(
- t *testing.T,
- symbolTable *tengo.SymbolTable,
- name string,
- expectedSymbol *tengo.Symbol,
- expectedDepth int,
- ) {
- actualSymbol, actualDepth, ok := symbolTable.Resolve(name, true)
- require.True(t, ok)
- require.Equal(t, expectedSymbol, actualSymbol)
- require.Equal(t, expectedDepth, actualDepth)
- }
|