소스 검색

FIX. 优化函数调用方法

RegMs If 4 년 전
부모
커밋
d6717bcc71
7개의 변경된 파일88개의 추가작업 그리고 91개의 파일을 삭제
  1. 2 2
      bind.go
  2. 1 1
      ctrl.go
  3. 1 1
      in
  4. 2 2
      list.go
  5. BIN
      mua
  6. 5 6
      mua.go
  7. 77 79
      type.go

+ 2 - 2
bind.go

@@ -11,7 +11,7 @@ func assign(s string, index []string, val string, envs []environ) string {
 	if len(index) == 0 {
 		return val
 	}
-	list, _ := parseList(s)
+	list := parseList(s)
 	i := toInt(value{word: index[0]}, envs)
 	return spliceList(list, i, 1, assign(indexOfList(list, i), index[1:], val, envs))
 }
@@ -50,7 +50,7 @@ func getValue(s string, envs []environ) (value, error) {
 			if len(index) > 0 {
 				val = value{word: toString(val)}
 				for _, i := range index {
-					list, _ := parseList(val.word)
+					list := parseList(val.word)
 					r := strings.Split(i, ":")
 					if len(r) == 1 {
 						val = value{word: indexOfList(list, toInt(value{word: r[0]}, envs))}

+ 1 - 1
ctrl.go

@@ -8,7 +8,7 @@ func opRun(val1 value, envs []environ) (value, bool) {
 	if !isList(val1) {
 		panic(fmt.Errorf("run: %s", errListExpected))
 	}
-	return interpret(&scanProvider{isList: true, list: val1.split[1 : len(val1.split)-1]}, envs)
+	return interpret(&scanProvider{isList: true, list: val1.list}, envs)
 }
 
 func opIf(val1, val2, val3 value, envs []environ) (value, bool) {

+ 1 - 1
in

@@ -66,7 +66,7 @@ make "x 1
 print :arr[x:]
 
 print word "hello "world
-print word "hello TRUE
+print word "hello true
 print word "hello -134.5
 
 print sentence 483 "dba

+ 2 - 2
list.go

@@ -5,7 +5,7 @@ import (
 	"strings"
 )
 
-func parseList(s string) ([]string, []string) {
+func parseList(s string) []string {
 	if !isList(value{word: s}) {
 		panic(fmt.Errorf("list: %s (%s)", errListExpected, s))
 	}
@@ -22,7 +22,7 @@ func parseList(s string) ([]string, []string) {
 			start = i + 1
 		}
 	}
-	return resList, list
+	return resList
 }
 
 func makeList(list []string) string {

BIN
mua


+ 5 - 6
mua.go

@@ -26,7 +26,6 @@ type value struct {
 	num   float64
 	word  string
 	list  []string
-	split []string
 	param []string
 	body  []string
 	env   environ
@@ -53,7 +52,7 @@ func interpret(scanner *scanProvider, envs []environ) (val value, returned bool)
 				val = toValue(opThing(val, envs), envs[0])
 			}
 			stack = append(stack, val)
-		} else if s[0] == '[' {
+		} else if s[0] == '[' && !scanner.isList {
 			list, bracketCnt := []string{}, 0
 			for {
 				leading := len(s) - len(strings.TrimLeft(s, "["))
@@ -204,7 +203,7 @@ func interpret(scanner *scanProvider, envs []environ) (val value, returned bool)
 					for j, name := range val.param {
 						local[name] = stack[i+1+j]
 					}
-					stack[i], _ = opRun(value{tp: typeList, split: val.body}, []environ{local, val.env, envs[2]})
+					stack[i], _ = opRun(value{tp: typeList, list: val.body}, []environ{local, val.env, envs[2]})
 					stack = stack[:i+1]
 					updated = true
 				}
@@ -215,10 +214,10 @@ func interpret(scanner *scanProvider, envs []environ) (val value, returned bool)
 		}
 	}
 	if len(stack) == 0 {
-		val = value{tp: typeList, list: []string{}, split: []string{"[", "]"}}
-		return
+		val = value{tp: typeList, list: []string{}}
+	} else {
+		val = toValue(stack[len(stack)-1], envs[0])
 	}
-	val = toValue(stack[len(stack)-1], envs[0])
 	return
 }
 

+ 77 - 79
type.go

@@ -11,9 +11,9 @@ import (
 const (
 	typeUnknown = iota
 	typeNumber
+	typeBool
 	typeWord
 	typeList
-	typeBool
 )
 
 const (
@@ -25,34 +25,6 @@ const (
 var nameExp = regexp.MustCompile(`^"` + _name + "$")
 var nameWithIndexExp = regexp.MustCompile(`^"` + _name + `((\[` + _index + `])*\[` + _index + `\\])?$`)
 
-func isName(val value) bool {
-	return nameExp.MatchString(val.word)
-}
-
-func toName(val value) string {
-	if !isName(val) {
-		panic(fmt.Errorf("name: %s", errInvalidName))
-	}
-	return val.word[1:]
-}
-
-func isNameWithIndex(val value) bool {
-	return nameWithIndexExp.MatchString(val.word)
-}
-
-func toNameWithIndex(val value) (string, []string) {
-	if !isNameWithIndex(val) {
-		panic(fmt.Errorf("name: %s", errInvalidName))
-	}
-	index := strings.Split(val.word, "[")
-	name, cnt := index[0][1:], len(index)-1
-	for i := 1; i < cnt; i++ {
-		index[i] = index[i][:len(index[i])-1]
-	}
-	index[cnt] = index[cnt][:len(index[cnt])-2]
-	return name, index[1:]
-}
-
 func isNumber(val value) bool {
 	if val.tp == typeNumber {
 		return true
@@ -101,6 +73,35 @@ func toInt(val value, envs []environ) int {
 	return int(num)
 }
 
+func isBool(val value) bool {
+	if val.tp == typeBool {
+		return true
+	}
+	if val.tp == typeNumber && (val.num == 0 || val.num == 1) {
+		return true
+	}
+	if isWord(val) {
+		val.word = val.word[1:]
+	}
+	return val.word == "true" || val.word == "false"
+}
+
+func toBool(val value) bool {
+	if val.tp == typeBool {
+		return val.b
+	}
+	if val.tp == typeNumber && (val.num == 0 || val.num == 1) {
+		return val.num == 1
+	}
+	if isWord(val) {
+		val.word = val.word[1:]
+	}
+	if val.word != "true" && val.word != "false" {
+		panic(fmt.Errorf("bool: %s", errInvalidBool))
+	}
+	return val.word == "true"
+}
+
 func isWord(val value) bool {
 	if val.tp == typeWord {
 		return true
@@ -134,6 +135,34 @@ func escapeWord(s string) string {
 	return s
 }
 
+func isName(val value) bool {
+	return nameExp.MatchString(val.word)
+}
+
+func toName(val value) string {
+	if !isName(val) {
+		panic(fmt.Errorf("name: %s", errInvalidName))
+	}
+	return val.word[1:]
+}
+
+func isNameWithIndex(val value) bool {
+	return nameWithIndexExp.MatchString(val.word)
+}
+
+func toNameWithIndex(val value) (string, []string) {
+	if !isNameWithIndex(val) {
+		panic(fmt.Errorf("name: %s", errInvalidName))
+	}
+	index := strings.Split(val.word, "[")
+	name, cnt := index[0][1:], len(index)-1
+	for i := 1; i < cnt; i++ {
+		index[i] = index[i][:len(index[i])-1]
+	}
+	index[cnt] = index[cnt][:len(index[cnt])-2]
+	return name, index[1:]
+}
+
 func isList(val value) bool {
 	if val.tp == typeList {
 		return true
@@ -142,52 +171,21 @@ func isList(val value) bool {
 }
 
 func parseFunc(s string, env environ) value {
-	list, split := parseList(s)
+	list := parseList(s)
 	if len(list) != 2 || !isList(value{word: list[0]}) || !isList(value{word: list[1]}) {
-		return value{tp: typeList, list: list, split: split}
+		return value{tp: typeList, list: list}
 	}
-	param, _ := parseList(list[0])
+	param := parseList(list[0])
 	for _, name := range param {
 		if !isName(value{word: `"` + name}) {
-			return value{tp: typeList, list: list, split: split}
+			return value{tp: typeList, list: list}
 		}
 	}
 	local := environ{}
 	for name, val := range env {
 		local[name] = val
 	}
-	return value{tp: typeList, list: list, split: split, param: param, body: strings.Split(list[1], " "), env: local}
-}
-
-func isBool(val value) bool {
-	if val.tp == typeBool {
-		return true
-	}
-	if val.tp == typeNumber && (val.num == 0 || val.num == 1) {
-		return true
-	}
-	if isWord(val) {
-		val.word = val.word[1:]
-	}
-	_, err := strconv.ParseBool(val.word)
-	return err == nil
-}
-
-func toBool(val value) bool {
-	if val.tp == typeBool {
-		return val.b
-	}
-	if val.tp == typeNumber && (val.num == 0 || val.num == 1) {
-		return val.num == 1
-	}
-	if isWord(val) {
-		val.word = val.word[1:]
-	}
-	b, err := strconv.ParseBool(val.word)
-	if err != nil {
-		panic(fmt.Errorf("bool: %s", errInvalidBool))
-	}
-	return b
+	return value{tp: typeList, list: list, param: param, body: parseList(list[1]), env: local}
 }
 
 func isEmpty(val value) bool {
@@ -207,15 +205,15 @@ func toValue(val value, env environ) value {
 	if isNumber(val) {
 		return value{tp: typeNumber, num: toNumber(val)}
 	}
+	if isBool(val) {
+		return value{tp: typeBool, b: toBool(val)}
+	}
 	if isWord(val) {
 		return parseWord(val.word)
 	}
 	if isList(val) {
 		return parseFunc(val.word, env)
 	}
-	if isBool(val) {
-		return value{tp: typeBool, b: toBool(val)}
-	}
 	panic(fmt.Errorf("value: %s", errValueExpected))
 }
 
@@ -223,36 +221,36 @@ func toString(val value) string {
 	if val.tp == typeNumber {
 		return strconv.FormatFloat(val.num, 'g', -1, 64)
 	}
+	if val.tp == typeBool {
+		return strconv.FormatBool(val.b)
+	}
 	if val.tp == typeWord {
 		return val.word[1:]
 	}
 	if val.tp == typeList {
 		return makeList(val.list)
 	}
-	if val.tp == typeBool {
-		return strconv.FormatBool(val.b)
-	}
 	panic(fmt.Errorf("string: %s", errValueExpected))
 }
 
-func opIsName(val1 value) value {
-	return value{tp: typeBool, b: isName(val1)}
-}
-
 func opIsNumber(val1 value) value {
 	return value{tp: typeBool, b: isNumber(val1)}
 }
 
+func opIsBool(val1 value) value {
+	return value{tp: typeBool, b: isBool(val1)}
+}
+
 func opIsWord(val1 value) value {
 	return value{tp: typeBool, b: isWord(val1)}
 }
 
-func opIsList(val1 value) value {
-	return value{tp: typeBool, b: isList(val1)}
+func opIsName(val1 value) value {
+	return value{tp: typeBool, b: isName(val1)}
 }
 
-func opIsBool(val1 value) value {
-	return value{tp: typeBool, b: isBool(val1)}
+func opIsList(val1 value) value {
+	return value{tp: typeBool, b: isList(val1)}
 }
 
 func opIsEmpty(val1 value) value {