我的BASIC语言解释器(My BASIC Interpreter)

这一段时间由于要找工作,因此,如果幸运地获得面试的机会的话(现在多么不容易啊),作为一名软件工程师,我免不了要被问大量的技术性问题。但由于现在不工作,平时不用的话,这些知识很容易被大脑驱逐出主要存储区域,而转到类似“SWAP”的地方。遗憾的是,大脑不比电脑,从“SWAP”里调东西不只是慢一些的问题,而是需要极其复杂的手续,比如催眠、打坐冥想、灵机一动、状态极佳等等,都是在面试时不太现实的。因此,必须多多使用这些知识,让大脑认为它们很重要,从而调到主要的快速存储区域里去。这样才有望在面试中对答如流。

但是,作为超级现实主义的本人来说,弄一些没用的东西是对时间和生命的极大浪费。因此,我就给自己设计了一个有用的项目:做一个BASIC语言解释器,将来可以加入很多算法、统计学、金融相关的计算功能,作为一种“内嵌语言”工具来使用。经过一段时间的努力,终于初步成型。目前还达不到1.0版的要求,但已经能正常执行很多程序,并能评价各种表达式的值。

另,还有一个做该项目的原因:我在之前的工作中用到某大公司的一个系统,他们提供TCL作为可编程的借口和内嵌语言。我的工作模式是:编写各种计算程序,并将各种功能做成TCL命令,跟TCL系统结合起来。然后,就是用TCL编写脚本程序来实现公司的各种计算需求。但TCL语言是一种功能很弱的语言,不但无法评价表达式的值(必须用expr命令来评价,十分麻烦),而且其各种流程控制结构也很笨拙。其他常用的语言,比如Python,我不喜欢它对程序书写格式的限制(比如每行前面要加多少个制表符等),把它跟C++或Java语言程序集成在一起也很令人头疼;而JavaScript(Rhino)我也不喜欢。因此,我就想做一个更好的,以便将来有用。选择BASIC语言的原因,一方面是BASIC十分简单易用,而又提供足够的威力来控制流程和进行计算;另一方面,BASIC语言是我在多年前(高中时)学的第一种编程语言,可能跟比尔·盖茨似的,对它有某种感情吧。

目前的版本大约达到0.6版的程度了吧?主要功能都实现了,但还没有支持数组(多维)、日期和时间计算以及将来要加入的各种算法、统计计算和金融计算等。目前的状态也不是一个嵌入式语言,而是一个命令行BASIC解释器或命令行表达式评价程序的形式。该程序会把结果输出到stdout(标准输出设备),并返回0。如果有错误发生,则向stderr(标准错误设备)输出错误信息,并返回1。本软件为非开源的免费软件,可免费使用和传播,但禁止把它单独或作为系统的一部分销售给他人。可以在这里下载。

由于本来的目的是把它作为嵌入式语言工具使用,因此,只保留了BASIC语言中一些主要的功能(精华?),把那些陈芝麻烂谷子的糟粕通通舍弃了。同时,又从Visual Basic里借来一些新的特性(比如:函数的参数按引用传递、用RETURN返回、循环体内的CONTINUE等)。

本软件用C++(以及STL)编写,没用其他第三方软件(比如yacc等)。

该软件的使用方法:

mybasic -e <表达式>

或者

mybasic -f <BASIC程序的文件名>

演示:

my-basic-demo

演示的程序(test.bas):

function mySum (byval x as integer) as integer
	if x <= 1 then
		return x
	else
		return x + mySum(x - 1)
	end if
end function

print mysum(100)

本程序的规格说明:

表达式评价

表达式以BASIC语言的语法书写。该程序支持算术、字符串、关系和逻辑运算。

数据类型

  • boolean
  • integer
  • double
  • string

运算符

  • 数学运算符: ^, +(一元运算符), -(一元运算符), *, /, \, MOD, +, –
  • 字符串运算符: +
  • 关系运算符: =, <>, <, <=, >, >=
  • 逻辑运算符: NOT, AND, OR
  • 其他: (, ) (圆括号,为了改变运算符的优先级)

数学函数

abs, sign, int, sqrt, exp, log, log10, rad(角度变弧度), deg(弧度变角度), sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh, sec, csc, pi(返回圆周率), random(返回[0, 1]区间内的随机数)

字符串函数

str(num)(数字变字符串), space(n), tab(n), ltrim(str), rtrim(str), trim(str), len(str), ucase(str), lcase(str), val(str)(字符串变数字), isNumeric(str), left(str, n), right(str, n), mid(str, from, n), instr(str1, str2)(如果str1中含有str2,则返回从0开始的索引;如果没有,则返回-1。)

与BASIC语言不同的地方

  • 一些函数的函数名不同。比如,不是“sqr”,而是“sqrt”。
  • 字符串的索引从0开始,而不是从1开始。
  • 不支持BASIC语言的类型字符(比如,“2#”表示double型的2),因为这些实在令人讨厌。。。

BASIC 解释器

本BASIC解释器支持一个实用简练的 BASIC 语法。

“实用简练的 BASIC 语法”的规格(除了上述的表达式规格以外):

支持的特性

  • 注释:REM, ‘(单引号)
  • 变量声明:DIM … AS …
  • 条件语句(块IF):IF, THEN, ELSEIF, ELSE, END IF
  • FOR循环:FOR, TO, STEP, NEXT, CONTINUE FOR, EXIT FOR
  • DO循环:DO, WHILE, UNTIL, LOOP, CONTINUE DO, EXIT DO
  • 函数和过程:FUNCTION, END FUNCTION, SUB, END SUB, RETURN, BYVAL, BYREF
  • 输出:PRINT
  • 其他:END

不支持的特性

  • LET(最没用的命令。直接无视之。)
  • 行号(太古老陈旧)
  • GOTO(万恶之源)
  • GUSUB…RETURN(太古老陈旧)
  • DEF FN(太古老陈旧)
  • 标签(label)(既然GOTO、GOSUB等都舍弃掉了,也就没有必要使用标签了)
  • 单行的IF
  • READ…DATA(太古老陈旧)
  • SELECT CASE(不喜欢该语法。但又不想加入如C++的switch/case等太不一样的东西。可以用IF代替。)
  • ON [ERROR] …(太古老陈旧)
  • WHILE … WEND(太古老陈旧,应以更强大的 DO … LOOP 代替)
  • EXIT SUB, EXIT FUNCTION(应以 RETURN 代替)
  • CALL(函数有返回类型凭什么就不能像过程那样直接调用?用CALL太麻烦,去掉。)
  • variant 数据类型(降低代码质量)
  • 用户定义类型(比如“类”等,因为实现太麻烦,而且在短小的脚本编程中并不需要。你要写较长的脚本?那为什么不选择一种严肃的语言呢?比如Java、C++等。)
  • PRINT USING(如果必要,可考虑将来加进去)
  • 文件 I/O(OPEN 等。在以后的版本中会加入新的文件I/O函数)

与一般的 BASIC 的不同之处

  • 变量必须声明(用DIM)之后才能使用(相当于在 VB 中总是声明“OPTIONAL EXPLICIT”。为了提高代码质量。)
  • “DIM a, b, c AS DOUBLE”可以,但不支持“DIM a AS INTEGER, b AS DOUBLE”(为了提高代码质量,使程序易读)
  • Boolean型和Integer型不能相互转换(为了提高代码质量)
  • 函数或过程:必须声明 BYVAL 或 BYREF(没有缺省。为了提高代码质量。)
  • PRINT 语句中:
    • “,”意思是插入制表符,而不是从某一列开始打印(原来的规格太古老陈旧,已不适用于今天的使用环境)
    • “;”意思是紧接着上次的地方打印。这跟原规格相同,但不会在数字前自动插入一个空格(必要时,程序员应该负责做这项工作)

尚未支持的特性(会在将来的版本中支持)

  • 数据类型
    • 数组(多维)
      • 数组的下标总是从0开始
      • 在“DIM A(N) AS INTEGER”语句中,N 是指数组的大小,不是最大下标(最大下标为 N – 1)
    • date
    • time
    • datetime
  • 内置函数
    • 一些统计类函数
    • 一些数值算法
    • 文件 I/O
    • 其他的互操作性(?)
  • 命令
    • INPUT (?)

2 thoughts on “我的BASIC语言解释器(My BASIC Interpreter)

  1. wrx

    Hi, 不知这个软件近况如何了。我也写过一个 BASIC 解释器,https://github.com/paladin-t/my_basic。巧合的是我们两个的有点撞名了,我的叫 MY-BASIC。

    Reply
    1. iDog 文章作者

      这个项目是我在比较长期的失业期间,为了维持自己的编程“体力”而做的,当然也是为了做些以后可能要用到的东西。但自从再次开始工作后,就一直未能着手去做。周末等空闲时间考虑的也主要是财务和佛学等方面的事,因为平日工作里考虑的IT的事情已经够多了……近来出了一些C++的新版本,也许过段时间我会为了学习新版本而继续开发一下这个项目。

      我看了你的项目,实现了BASIC里的一些主要功能,而且用C编写,使得它更加小巧,很不错的。

      Reply

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注