当前位置:   article > 正文

用Go语言开发一个编程语言_如何编写一门类似golang的自己的语言

如何编写一门类似golang的自己的语言

Go语言开发一个编程语言

最近小弟业余时间闲来无事,所以就尝试一下自己开发一个轻量级的解释型语言。

出于学习的目的,我目前已经利用业余时间开发了一个多月,目前实现了变量声明,内置函数调用、自定义函数的声明和调用、算术表达式(这个最难了),其余功能仍然在持续迭代中。

github 地址 : https://github.com/pywee/lit

暂且我将这个语言命名为 Lit,以下是我已经实现的特性,仍然有一些小bug需要持续修复,感兴趣的话给个 star.

使用方法
go get github.com/pywee/lit
  • 1

一、变量声明

import "github.com/pywee/lit"

func main() {
    // 执行以下句子,最终会输出
    src := []byte(`
        a = 123;
        b = a + 456;
        Print(b); // 579
    `)
    _, err := lit.NewExpr(src)
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

二、算术表达式的计算。算术符号的优先级保持与 Go 语言相同。请看示例:

    // 不同的语言符号优先级是不完全一样的,Lit 的算术符号优先级保持与 Golang 一致
    // 首先我们执行 Go 语言原生函数进行数学表达式计算
    // 以下句子最终会输出 
    // +1.600000e+001
    // 125
    println((2 + 100 ^ 2 - (10*1.1 - 22 + (22 | 11))) / 10 * 2)
    println(12/333+31+(5/10)-6|100)

    // 使用 Lit 计算文本中的数据
    // 表达式文本
    // 执行下面的句子 最终会输出
    exprs := []byte(`
        a = (2 + 100 ^ 2 - (10*1.1 - 22 + (22 | 11))) / 10 * 2;
        b = 12 / 333 + 31 + (5 / 10) - 6 | 100;
        Print(a); // 16
        Print(b); // 125
    `)
    _, err = lit.NewExpr(exprs)

    // *** 同样的表达式放在 PHP 中,会输出 -24 ***

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

三、当前已支持部分常用内置函数(测试阶段),更多的内置函数我将在接下来继续完成


    // 下面的句子调用了两个函数 
    // IsInt(arg) 用来检查 arg 是否为整型 
    // Replace(arg1, arg2, arg3, arg4) 用来做字符串替换

    // 执行下面语句 最终会输出
     exprs := []byte(`
        a = Replace("hello word111", "1", "", 2-IsInt((1+(1 + IsInt(123+(1+2)))-1)+2)-2);
        VarDump(a); // STRING hello word
    `)
    _, err = lit.NewExpr(exprs)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

四、弱类型转换,弱类型的这一特性我将它设计为与 PHP 基本一样

    // 当布尔值参与运算时,底层会将 true 转为 1, false 转为 0
    // 执行下面句子 将输出
    src := []byte(`
        a = true - 1;
        b = IsInt(1);
        c = IsFloat(1);
        d = false == 0.0;
        e = "false" == 0.0;
        Print(a); // 0
        Print(b); // true
        Print(c); // true
        Print(d); // true
        Print(e); // true
    `)
    _, err := lit.NewExpr(src)


    // 与其他弱类型语言一样
    // 字符串数字与整型相操作,在 Lit 的底层会将字符串数字转换为整型
    // 执行下面句子 将输出
    src := []byte(`
        a = "1" - 1;
        b =  0.0 >= false+1 || (1<=21 && 1==1);
        Print(a); // 0
        Print(b); // true
    `)
    _, err := lit.NewExpr(src)


    // 与其他弱类型语言一样
    // 字符串数字与整型相操作,在 Lit 的底层会将字符串数字转换为整型
    // 执行下面句子 将输出
    src := []byte(`
        a = "1" - 1;
        Print(a); // 0
    `)
    _, err := lit.NewExpr(src)


    // 字符串与字符串相加时 将进行字符串的拼接
    // 执行以下句子,将会输出
    src := []byte(`
        a = "abc" + "def";
        Print(a); // abcdef
    `)
    _, err := lit.NewExpr(src)


    // 但如果当两个字符串都为数字时 对他们进行相加 则会被底层转换为数字
    // 执行如下句子,将会输出
     src := []byte(`
        a = "123" + "456";
        Print(a); // 579
    `)
    _, err := lit.NewExpr(src)


    // 其他字符串+整型将会报错
    // 执行如下句子
    src := []byte(`
    	a = "abcwwww1230"+0.01;
    	Print(a); // 报错
    `)
    _, err := lit.NewExpr(src)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

五、“并且” 与 “或者” 符号处理

    // 执行如下句子,将会输出
    src := []byte(`
        a = IsInt(1) && 72+(11-2) || 1-false;
        VarDump(a); // BOOL true
    `)
    _, err := lit.NewExpr(src)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

六、自定义函数 (开发中…)

// 执行如下句子,将会输出
// 8 123
src := []byte(`
    a = "123";
    func max(b = 10, m = "2") {
        print(b - m, a);
    }
    max(); // 8 123
`)
_, err := lit.NewExpr(src)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

请注意,Lit 的算术符号优先级向 Golang 看齐。每个语言对算术符号的优先级处理都有一定区别,如,针对以下表达式进行计算时:

// 2 + 100 ^ 2 - (10*1.1 - 22 + (22 | 11)) / 10 * 2
// PHP 输出 -104
// Node.js 输出 -104
// Golang 输出 96
// Lit (lit) 输出 96
  • 1
  • 2
  • 3
  • 4
  • 5

Lit 算术符号优先级

第一级 () && ||

第一级 > < >= <= == != ===

第三级 * / %

第四级 | &

第五级 + - ^


当前支持的内置函数有如下,更多函数将会在逐步补充

    // 通用处理函数
    Print
    VarDump

    // 字符串处理函数
    // 函数的命名基本参考了 Go 语言
    // 除了个别函数有差别,如 
    // UTF8Len 用于检测字符串字数的函数
    // IsNumeric 用于判断当前输入是否为数字
    Trim
    TrimLeft
    TrimRight
    TrimSpace
    Len
    UTF8Len
    MD5
    Replace
    Contains
    Index
    LastIndex
    ToLower
    ToUpper
    ToTitle
    Repeat

    // 其他函数
    IsNumeric
    IsBool
    IsInt
    IsFloat
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
后期将会实现更多特性,敬请期待…

github 地址: https://github.com/pywee/lit

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/172840
推荐阅读
相关标签
  

闽ICP备14008679号