給 go 語言新增中文關鍵字
在知乎上看到這個文章,非常有意思,轉過來給大家一起分享。
一、新增中文關鍵字
涉及檔案:
go\src\go\token\token.go
//新增string陣列
var tokens_zh = [...]string{
BREAK: "破",
CASE: "例",
CHAN: "道",
CONST: "靜",
CONTINUE: "續",
DEFAULT: "默",
DEFER: "延",
ELSE: "另",
FALLTHROUGH: "繼",
FOR: "於",
FUNC: "函",
GO: "去",
GOTO: "到",
IF: "若",
IMPORT: "引",
INTERFACE: "接",
MAP: "圖",
PACKAGE: "包",
RANGE: "範",
RETURN: "回",
SELECT: "擇",
STRUCT: "構",
SWITCH: "轉",
TYPE: "型",
VAR: "變",
}
func init() {
keywords = make(map[string]Token)
for i := keyword_beg + 1; i < keyword_end; i++ {
keywords[tokens[i]] = i
//新增下面這一行
keywords[tokens_zh[i]] = i
}
}
go\src\cmd\compile\internal\syntax\scanner.go
//新增函式
func getZhTok(lit []byte) token {
switch string(lit) {
case "破": return _Break
case "例": return _Case
case "道": return _Chan
case "靜": return _Const
case "續": return _Continue
case "默": return _Default
case "延": return _Defer
case "另": return _Else
case "繼": return _Fallthrough
case "於": return _For
case "函": return _Func
case "去": return _Go
case "到": return _Goto
case "若": return _If
case "引": return _Import
case "接": return _Interface
case "圖": return _Map
case "包": return _Package
case "範": return _Range
case "回": return _Return
case "擇": return _Select
case "構": return _Struct
case "轉": return _Switch
case "型": return _Type
case "變": return _Var
default: return 0
}
}
func (s *scanner) ident() {
s.startLit()
// accelerate common case (7bit ASCII)
c := s.getr()
for isLetter(c) || isDecimal(c) {
c = s.getr()
}
// general case
if c >= utf8.RuneSelf {
for s.isIdentRune(c, false) {
c = s.getr()
}
}
s.ungetr()
lit := s.stopLit()
// possibly a keyword
if len(lit) >= 2 {
if tok := keywordMap[hash(lit)]; tok != 0 && tokStrFast(tok) == string(lit) {
s.nlsemi = contains(1<<_Break|1<<_Continue|1<<_Fallthrough|1<<_Return, tok)
s.tok = tok
return
} else if tok := getZhTok(lit); tok != 0 { // 新增 else if
s.nlsemi = contains(1<<_Break|1<<_Continue|1<<_Fallthrough|1<<_Return, tok)
s.tok = tok
return
}
}
s.nlsemi = true
s.lit = string(lit)
s.tok = _Name
}
二、 新增中文內建型別和函式
新增一部分主要的,builtin.go 也有很多內建函式,暫不涉及。
涉及檔案
go\src\cmd\compile\internal\gc\universe.go
var basicTypes = [...]struct {
name string
etype types.EType
}{
{"int8", TINT8},
{"整8", TINT8},
{"int16", TINT16},
{"整16", TINT16},
{"int32", TINT32},
{"整32", TINT32},
{"int64", TINT64},
{"整64", TINT64},
{"uint8", TUINT8},
{"無8", TUINT8},
{"uint16", TUINT16},
{"無16", TUINT16},
{"uint32", TUINT32},
{"無32", TUINT32},
{"uint64", TUINT64},
{"無64", TUINT64},
{"float32", TFLOAT32},
{"浮32", TFLOAT32},
{"float64", TFLOAT64},
{"浮64", TFLOAT64},
{"complex64", TCOMPLEX64},
{"復64", TCOMPLEX64},
{"complex128", TCOMPLEX128},
{"復128", TCOMPLEX128},
{"bool", TBOOL},
{"不二", TBOOL},
{"string", TSTRING},
{"字串", TSTRING},
}
//下面的新增需要修改lexinit1()
var typedefs = [...]struct {
name string
etype types.EType
sameas32 types.EType
sameas64 types.EType
}{
{"int", TINT, TINT32, TINT64},
{"整", TINT, TINT32, TINT64},
{"uint", TUINT, TUINT32, TUINT64},
{"無號", TUINT, TUINT32, TUINT64},
{"uintptr", TUINTPTR, TUINT32, TUINT64},
{"針", TUINTPTR, TUINT32, TUINT64},
}
var builtinFuncs = [...]struct {
name string
op Op
}{
{"append", OAPPEND},
{"附加", OAPPEND},
{"cap", OCAP},
{"容量", OCAP},
{"close", OCLOSE},
{"關閉", OCLOSE},
{"complex", OCOMPLEX},
{"複數", OCOMPLEX},
{"copy", OCOPY},
{"複製", OCOPY},
{"delete", ODELETE},
{"刪除", ODELETE},
{"imag", OIMAG},
{"虛部", OIMAG},
{"len", OLEN},
{"長度", OLEN},
{"make", OMAKE},
{"構建", OMAKE},
{"new", ONEW},
{"新建", ONEW},
{"panic", OPANIC},
{"報警", OPANIC},
{"print", OPRINT},
{"列印", OPRINT},
{"println", OPRINTN},
{"換行列印", OPRINTN},
{"real", OREAL},
{"實部", OREAL},
{"recover", ORECOVER},
{"復原", ORECOVER},
}
var unsafeFuncs = [...]struct {
name string
op Op
}{
{"Alignof", OALIGNOF},
{"取對齊", OALIGNOF},
{"Offsetof", OOFFSETOF},
{"取偏移", OOFFSETOF},
{"Sizeof", OSIZEOF},
{"取大小", OSIZEOF},
}
func lexinit() {
// 新增對應 true、false、nil、iota 的中文詞,其中iota是希臘第9個字母,象形一下^-^
s = builtinpkg.Lookup("真")
s.Def = asTypesNode(nodbool(true))
asNode(s.Def).Sym = lookup("true")
asNode(s.Def).Name = new(Name)
asNode(s.Def).Type = types.Idealbool
s = builtinpkg.Lookup("假")
s.Def = asTypesNode(nodbool(false))
asNode(s.Def).Sym = lookup("false")
asNode(s.Def).Name = new(Name)
asNode(s.Def).Type = types.Idealbool
s = builtinpkg.Lookup("無")
var v1 Val
v1.U = new(NilVal)
s.Def = asTypesNode(nodlit(v1))
asNode(s.Def).Sym = s
asNode(s.Def).Name = new(Name)
s = builtinpkg.Lookup("丨")
s.Def = asTypesNode(nod(OIOTA, nil, nil))
asNode(s.Def).Sym = s
asNode(s.Def).Name = new(Name)
}
func lexinit1() {
s = builtinpkg.Lookup("錯誤")
s.Def = asTypesNode(typenod(types.Errortype))
asNode(s.Def).Name = new(Name)
s = builtinpkg.Lookup("位元組")
s.Def = asTypesNode(typenod(types.Bytetype))
asNode(s.Def).Name = new(Name)
s = builtinpkg.Lookup("字元")
s.Def = asTypesNode(typenod(types.Runetype))
asNode(s.Def).Name = new(Name)
// typedefs的修改,程式碼需要修改成 的下面的樣子
// backend-dependent builtin types (e.g. int).
for _, s := range typedefs {
s1 := builtinpkg.Lookup(s.name)
t := types.Types[s.etype]
if t == nil {
sameas := s.sameas32
if Widthptr == 8 {
sameas = s.sameas64
}
simtype[s.etype] = sameas
minfltval[s.etype] = minfltval[sameas]
maxfltval[s.etype] = maxfltval[sameas]
minintval[s.etype] = minintval[sameas]
maxintval[s.etype] = maxintval[sameas]
t = types.New(s.etype)
t.Sym = s1
types.Types[s.etype] = t
if s.etype != TANY && s.etype != TSTRING {
dowidth(t)
}
}
s1.Def = asTypesNode(typenod(t))
asNode(s1.Def).Name = new(Name)
s1.Origpkg = builtinpkg
//dowidth(t)
}
}
三、 新增中文命令
例項:新增 “執行” 為 “run” 的同義命令
go 執行 test.go 等效 go run test.go
go.exe 的命令是通過解析 UsageLine 的文字來識別的。
例如:run 命令 UsageLine: "go run [build flags] [-exec xprog] package [arguments...]"
"go "後面,"["前面第一個詞 匹配就可以了
可以在路徑 go\src\cmd\go\下搜尋 UsageLine,查詢其他命令,進行修改新增。
涉及檔案
go\src\cmd\go\internal\run\run.go
var CmdZhRun = &base.Command{
UsageLine: "go 執行 [build flags] [-exec xprog] package [arguments...]",
Short: "編譯 和 執行 Go 程式",
Long: `
See also: go build.
`,
}
func init() {
CmdRun.Run = runRun // break init loop
CmdZhRun.Run = runRun
work.AddBuildFlags(CmdRun)
work.AddBuildFlags(CmdZhRun)
CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
CmdZhRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
}
go\src\cmd\go\main.go
func init() {
base.Go.Commands = []*base.Command{
run.CmdRun,
run.CmdZhRun,
}
四、 測試
本來想連 main、init 的函式名也加個中文的,但牽扯比較多,暫時作罷。
test.go
包 main
引 "fmt"
函 main() {
變 a []位元組 = []位元組("啦啦")
若 長度(字串(a)) == 6 {
列印("嘻嘻")
} 另 {
fmt.Println("哈嘍")
}
}
命令
go 執行 test.go
輸出
嘻嘻
原文地址:zhuanlan.zhihu.com/p/106104002
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go 語言 new 和 make 關鍵字的區別Go
- GO語言————4.1 檔名、關鍵字與識別符號Go符號
- Go語言的識別符號、關鍵字、字面量、型別Go符號型別
- c語言static關鍵字的理解C語言
- C語言的幾個關鍵字C語言
- 給《Laravel 中文文件》新增一個語言選擇選單Laravel
- Go 語言:The Laws of Reflection 中文版Go
- 【建議收藏】Go語言關鍵知識點總結Go
- 帶讀 |《Go in Action》(中文:Go語言實戰)(一)Go
- Go語言給編譯出來的程式新增圖示和版本資訊Go編譯
- C語言初學者必須掌握的關鍵字!C語言
- robotframework appiumLibrary新增自定義關鍵字FrameworkAPP
- JDK14 新增關鍵字——recordJDK
- 帶讀 |《Go in Action》(中文:Go語言實戰) 語法和語言結構概覽(三)Go
- 帶讀 |《Go in Action》(中文:Go語言實戰)語法和語言結構概覽 (二)Go
- 【Go語言繪圖】圖片新增文字(二)Go繪圖
- 【Go語言繪圖】圖片新增文字(一)Go繪圖
- C語言include關鍵字和引用.h .c的區別C語言
- sync.Pool:提高Go語言程式效能的關鍵一步Go
- C語言之static關鍵字C語言
- Go語言————1、初識GO語言Go
- go語言gRPC系列(二) - 為gRPC新增證書GoRPC
- 最新Go語言學習路線圖 帶你通關Go語言-千鋒Go
- 帶讀 |《Go in Action》(中文:Go語言實戰)打包和工具鏈Go
- 帶讀 |《Go in Action》(中文:Go語言實戰) 深入瞭解切片Go
- GoLand 2021 for Mac(Go語言商用IDE)中文版GoLandMacIDE
- # 關於select關鍵字語句定義順序# 關於select關鍵字語句執行順序
- Go 語言關於 Type Assertions 的 坑Go
- 【粉絲問答10】C語言關鍵字static的使用詳解C語言
- GO語言————8.6 將 map 的鍵值對調Go
- GO語言————2、GO語言環境安裝Go
- DM 關鍵字、遮蔽關鍵字
- 關於 vs code 中文語言包的 bug
- yield from 關鍵字的 return 語句
- C語言中volatile關鍵字的作用C語言
- C語言中static關鍵字詳解C語言
- C語言 關鍵字const的作用 const int* 和int *const 的區別C語言
- let關鍵字和const關鍵字