Playground:
Code:
enum动机
enumenumenumenumenumenumpackage task
type TaskStatus int
const (
Todo TaskStatus = iota
Pending
Done
)
现在,我们引入前端,因为数据库里存的是 0、1这样的数据,那前端拿到的 API 返回值往往也是这样子的,如
{
todos: [
{name: "Learning", status: 0}
]
}
statusenumenum TaskStatus {
Todo,
Pending,
Done
}
enum基于这样重复劳动的问题,所以就有了本文要所讲的这个小工具
转换
进行语言的转换,必须理解源语言所表达的含义,这里也就用到了传统的编译相关的一些技术
分词
分词就是将一句话分成一个个单词
how are you?howareyou?TaskStatus[]token.Token{
{
Value: "package",
Type: "Package",
Start: {0, 0},
End: {0, 6},
},
{
Value: "task",
Type: "Identifier",
Start: {0, 8},
End: {0, 11},
},
{
Value: "type",
Type: "Type",
Start: {2, 0},
End: {2, 3},
},
{
Value: "TaskStatus",
Type: "Identifier",
Start: {2, 5},
End: {2, 14},
},
{
Value: "int",
Type: "IntType",
Start: {2, 16},
End: {2, 18},
},
{
Value: "const",
Type: "Const",
Start: {4, 0},
End: {4, 5},
},
{
Value: "(",
Type: "LeftParentheses",
Start: {4, 6},
End: {4, 6},
},
{
Value: "Todo",
Type: "Identifier",
Start: {5, 1},
End: {5, 4},
},
{
Value: "TaskStatus",
Type: "Identifier",
Start: {5, 6},
End: {5, 15},
},
{
Value: "=",
Type: "Assignment",
Start: {5, 17},
End: {5, 17},
},
{
Value: "iota",
Type: "IOTA",
Start: {5, 19},
End: {5, 22},
},
{
Value: "Pending",
Type: "Identifier",
Start: {6, 1},
End: {6, 7},
},
{
Value: "Done",
Type: "Identifier",
Start: {7, 1},
End: {7, 4},
},
{
Value: ")",
Type: "RightParentheses",
Start: {8, 0},
End: {8, 0},
},
}分词的 workflow 如下
生成 AST
根据上一步分析出来的 token,生成对应的抽象语法树
ast.File{
Name: "task",
Body: {
ast.TypeDeclaration{
Id: "TaskStatus",
Kind: "int",
},
ast.ConstDeclaration{
BaseDeclaration: ast.BaseDeclaration{},
Declarators: {
{
Kind: "TaskStatus",
Id: "Todo",
Value: "iota",
},
{
Kind: "",
Id: "Pending",
Value: "",
},
{
Kind: "",
Id: "Done",
Value: "",
},
},
},
},
}
typeStatusinttokenTypeDeclarationfunc (a *AstGenerator) readTypeDeclaration() TypeDeclaration {
d := TypeDeclaration{}
next, _ := a.nextToken(true)
d.Id = next.Value
next, _ = a.nextToken(true)
if next.Type == token.IntType {
d.Kind = Int
} else {
d.Kind = String
}
return d
}执行 AST
enum遍历上一步生成的 AST,生成相关的计算值
{
TaskStatus: {
Todo: 0,
Pending: 1,
Done: 2
}
}enumenumenumnamespace task {
export enum TaskStatus {
Done = 2,
Pending = 1,
Todo = 0,
}
}
Playground
因为转换的源代码是用 Golang 写的,所以这里是将 Golang 变异成 wasm 运行在浏览器的