Skip to content

Commit

Permalink
移除 stlib_string 部分方法
Browse files Browse the repository at this point in the history
  • Loading branch information
lollipopkit committed Oct 26, 2022
1 parent 42ed4b9 commit b6cb1b6
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 234 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"request": "launch",
"mode": "debug",
"program": ".",
"args": ["test/basic.lk"]
"args": ["test/test.lk"]
},

]
Expand Down
2 changes: 0 additions & 2 deletions compiler/parser/parse_exp.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ exp2 ::= {(‘not’ | ‘#’ | ‘-’ | ‘~’)} exp1
exp1 ::= exp0 {‘^’ exp2}
exp0 ::= nil | false | true | Numeral | LiteralString
| ‘...’ | functiondef | prefixexp | tableconstructor
| closure
closure ::= ‘(’ explist ‘)’ ‘=>’ exp
*/
func parseExp(lexer *Lexer) Exp {
return parseExp14(lexer)
Expand Down
2 changes: 1 addition & 1 deletion compiler/parser/parse_stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func parseAssignOrFuncCallStat(lexer *Lexer) Stat {
}
}

// varlist ‘=’ explist |
// varlist ‘=’ explist
func parseAssignStat(lexer *Lexer, var0 Exp) Stat {
varList := _finishVarList(lexer, var0) // varlist
if lexer.LookAhead() == TOKEN_OP_ASSIGNSHY {
Expand Down
21 changes: 21 additions & 0 deletions state/lua_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,27 @@ func getMetafield(val any, fieldName string, ls *luaState) any {
return nil
}

func SetExtension(typ, fnName string, c *closure, ls *luaState) {
key := fmt.Sprintf("_EXT|%s", typ)
if ext, ok := ls.registry.get(key).(*luaTable); ok {
ext.put(fnName, c)
} else {
ext = newLuaTable(0, 0)
ext.put(fnName, c)
ls.registry.put(key, ext)
}
}

func GetExtension(typ, fnName string, ls *luaState) *closure {
key := fmt.Sprintf("_EXT|%s", typ)
if ext, ok := ls.registry.get(key).(*luaTable); ok {
if c, ok := ext.get(fnName).(*closure); ok {
return c
}
}
return nil
}

func callMetamethod(a, b any, mmName string, ls *luaState) (any, bool) {
var mm any
if mm = getMetafield(a, mmName, ls); mm == nil {
Expand Down
156 changes: 1 addition & 155 deletions stdlib/lib_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,13 @@ import (

var strLib = map[string]GoFunction{
"len": strLen,
"rep": strRep,
"repeat": strRep,
"reverse": strReverse,
"lower": strLower,
"upper": strUpper,
"sub": strSub,
"byte": strByte,
"char": strChar,
"dump": strDump,
"packsize": strPackSize,
"pack": strPack,
"unpack": strUnpack,
"find": strFind,
"match": strMatch,
"gsub": strGsub,
"gmatch": strGmatch,
}

func OpenStringLib(ls LkState) int {
Expand Down Expand Up @@ -174,44 +166,6 @@ func strChar(ls LkState) int {
return 1
}

// string.dump (function [, strip])
// http://www.lua.org/manual/5.3/manual.html#pdf-string.dump
// lua-5.3.4/src/lstrlib.c#str_dump()
func strDump(ls LkState) int {
// strip := ls.ToBoolean(2)
// ls.CheckType(1, LUA_TFUNCTION)
// ls.SetTop(1)
// ls.PushString(string(ls.Dump(strip)))
// return 1
panic("todo: strDump!")
}

/* PACK/UNPACK */

// string.packsize (fmt)
// http://www.lua.org/manual/5.3/manual.html#pdf-string.packsize
func strPackSize(ls LkState) int {
fmt := ls.CheckString(1)
if fmt == "j" {
ls.PushInteger(8) // todo
} else {
panic("todo: strPackSize!")
}
return 1
}

// string.pack (fmt, v1, v2, ···)
// http://www.lua.org/manual/5.3/manual.html#pdf-string.pack
func strPack(ls LkState) int {
panic("todo: strPack!")
}

// string.unpack (fmt, s [, pos])
// http://www.lua.org/manual/5.3/manual.html#pdf-string.unpack
func strUnpack(ls LkState) int {
panic("todo: strUnpack!")
}

func _fmtArg(tag string, ls LkState, argIdx int) string {
switch tag[len(tag)-1] { // specifier
case 'c': // character
Expand All @@ -234,111 +188,3 @@ func _fmtArg(tag string, ls LkState, argIdx int) string {
panic("todo! tag=" + tag)
}
}

/* PATTERN MATCHING */

// string.find (s, pattern [, init [, plain]])
// http://www.lua.org/manual/5.3/manual.html#pdf-string.find
func strFind(ls LkState) int {
s := ls.CheckString(1)
sLen := len(s)
pattern := ls.CheckString(2)
init := posRelat(ls.OptInteger(3, 1), sLen)
if init < 1 {
init = 1
} else if init > sLen+1 { /* start after string's end? */
ls.PushNil()
return 1
}
plain := ls.ToBoolean(4)

start, end := find(s, pattern, init, plain)

if start < 0 {
ls.PushNil()
return 1
}
ls.PushInteger(int64(start))
ls.PushInteger(int64(end))
return 2
}

// string.match (s, pattern [, init])
// http://www.lua.org/manual/5.3/manual.html#pdf-string.match
func strMatch(ls LkState) int {
s := ls.CheckString(1)
sLen := len(s)
pattern := ls.CheckString(2)
init := posRelat(ls.OptInteger(3, 1), sLen)
if init < 1 {
init = 1
} else if init > sLen+1 { /* start after string's end? */
ls.PushNil()
return 1
}

captures := match(s, pattern, init)

if captures == nil {
ls.PushNil()
return 1
} else {
for i := 0; i < len(captures); i += 2 {
capture := s[captures[i]:captures[i+1]]
ls.PushString(capture)
}
return len(captures) / 2
}
}

// string.gsub (s, pattern, repl [, n])
// http://www.lua.org/manual/5.3/manual.html#pdf-string.gsub
func strGsub(ls LkState) int {
s := ls.CheckString(1)
pattern := ls.CheckString(2)
repl := ls.CheckString(3) // todo
n := int(ls.OptInteger(4, -1))

newStr, nMatches := gsub(s, pattern, repl, n)
ls.PushString(newStr)
ls.PushInteger(int64(nMatches))
return 2
}

// string.gmatch (s, pattern)
// http://www.lua.org/manual/5.3/manual.html#pdf-string.gmatch
func strGmatch(ls LkState) int {
s := ls.CheckString(1)
pattern := ls.CheckString(2)

gmatchAux := func(ls LkState) int {
captures := match(s, pattern, 1)
if captures != nil {
for i := 0; i < len(captures); i += 2 {
capture := s[captures[i]:captures[i+1]]
ls.PushString(capture)
}
s = s[captures[len(captures)-1]:]
return len(captures) / 2
} else {
return 0
}
}

ls.PushGoFunction(gmatchAux)
return 1
}

/* helper */

/* translate a relative string position: negative means back from end */
func posRelat(pos int64, _len int) int {
_pos := int(pos)
if _pos >= 0 {
return _pos
} else if -_pos > _len {
return 0
} else {
return _len + _pos + 1
}
}
86 changes: 11 additions & 75 deletions stdlib/str.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,80 +36,16 @@ func parseFmtStr(fmt string) []string {
return parsed
}

func find(s, pattern string, init int, plain bool) (start, end int) {
tail := s
if init > 1 {
tail = s[init-1:]
}

if plain {
start = strings.Index(tail, pattern)
end = start + len(pattern) - 1
} else {
re, err := _compile(pattern)
if err != "" {
panic(err) // todo
} else {
loc := re.FindStringIndex(tail)
if loc == nil {
start, end = -1, -1
} else {
start, end = loc[0], loc[1]-1
}
}
}
if start >= 0 {
start += len(s) - len(tail) + 1
end += len(s) - len(tail) + 1
}

return
}

func match(s, pattern string, init int) []int {
tail := s
if init > 1 {
tail = s[init-1:]
}

re, err := _compile(pattern)
if err != "" {
panic(err) // todo
} else {
found := re.FindStringSubmatchIndex(tail)
if len(found) > 2 {
return found[2:]
} else {
return found
}
}
}

// todo
func gsub(s, pattern, repl string, n int) (string, int) {
re, err := _compile(pattern)
if err != "" {
panic(err) // todo
} else {
indexes := re.FindAllStringIndex(s, n)
if indexes == nil {
return s, 0
}

nMatches := len(indexes)
lastEnd := indexes[nMatches-1][1]
head, tail := s[:lastEnd], s[lastEnd:]

newHead := re.ReplaceAllString(head, repl)
return newHead + tail, nMatches
}
}

func _compile(pattern string) (*regexp.Regexp, string) {
re, err := regexp.Compile(pattern)
if err != nil {
return nil, err.Error() // todo
/* helper */

/* translate a relative string position: negative means back from end */
func posRelat(pos int64, _len int) int {
_pos := int(pos)
if _pos >= 0 {
return _pos
} else if -_pos > _len {
return 0
} else {
return re, ""
return _len + _pos + 1
}
}
}

0 comments on commit b6cb1b6

Please sign in to comment.