我正在为quazi JavaScript语言编写一个简单的解释器。在JavaScript中,变量的类型由它的值定义。我试图谷歌一些简单的源代码解决方案或一些解释如何做这种事情。我不知道在哪里寻求帮助,这就是为什么我要问你们一些文章或git的项目。感谢!!!
答案 0 :(得分:1)
在JavaScript中,变量实际上不是具有类型。 值具有类型,变量具有值。您可以检查变量的当前值的类型,但始终可以为变量分配任何其他值。有时用于此类变量的术语是“变体”。这是您可以为您的语言选择的一个选项。
如果您想要输入类型变量,则需要对表达式进行静态分析。解析一行代码后,例如:
var x = a.function() + b;
...在开始执行之前,您需要查看a.function
和b
以确定它们将返回的数据类型,然后派生{{1}的类型返回给出这两个类型作为输入 - 然后可以将其指定为operator +
的变量类型。
这要做更多的工作,并引入了一个全新的错误类别,阻止代码首先执行(“编译时”错误)。
您可能正在寻找第一种方法,对于该方法,您需要一个将值与值类型的描述相结合的数据结构,并且该单元是您分配给变量,执行计算,如果你很幸运,你正在编写解释器的语言已经有了这样的概念 - 例如,如果你用JavaScript编写解释器,那么你可以直接使用值,因为他们已经封装了这个概念。如果您使用Java或C#编写解释器,则x
类型可以引用任何值,并且语言的类型系统(以及必要时的反射)可用于检查类型。
希望有所帮助!
答案 1 :(得分:1)
存储各种类型的变量类型称为"变体"。基本上,你所做的是每个变量必须足够大以容纳你的语言所具有的所有类型,加上标记当前的类型。例如,在C中你可以使用联盟:
struct Variant
{
enum VariantTypeEnum
{
VARIANT_TYPE_INT,
VARIANT_TYPE_STRING,
VARIANT_TYPE_BOOL
} type;
union VariantUnion
{
int intValue;
char* stringValue;
bool boolValue;
} value;
};
当你有这种类型的变量时,你现在可以为它分配两种类型并标记它是哪一种,然后根据它的类型运行不同的代码:
Variant x;
x.type = VARIANT_TYPE_INT;
x.value.intValue = 42;
通常你会写一个效用函数转换成所需的类型,这样你的翻译就不必担心它实际上是什么类型,除非它是一个它无法转换的类型到:
char* CopyStringFromVariant( Variant* inVariant )
{
if( inVariant->type == VARIANT_TYPE_STRING )
{
int strSize = strlen(inVariant.value.stringValue) +1;
char* strCopy = malloc(strSize);
memmove(strCopy,inVariant.value.stringValue, strSize);
return strCopy;
}
else if( inVariant->type == VARIANT_TYPE_BOOL )
{
const char* boolStr = inVariant.value.boolValue ? "true" : "false";
int strSize = strlen(boolStr) +1;
char* strCopy = malloc(strSize);
memmove(strCopy, boolStr, strSize);
return strCopy;
}
else if( inVariant->type == VARIANT_TYPE_INT )
{
char strBuf[11] = {};
snprintf( strBuf, sizeof(strBuf) -1, "%d", inVariant.value.intValue );
int strSize = strlen(strBuf) +1;
char* strCopy = malloc(strSize);
memmove(strCopy, strBuf, strSize);
return strCopy;
}
else
return NULL; // Indicate error.
}
如果你没有编写一个纯粹的行式解释器(即这不是人为限制的家庭作业),但是允许创建一些混合,你可以先将代码解析成树形结构,然后走树节点并找出它们的类型。根据应用的操作,使用位字段或集合来跟踪存储在变量中的值的类型。例如。如果存在变量中存在除法结果,那么最终结果必须从那时起是一个数字。
一旦您分析了整个脚本,就可以生成代码。这适用于大多数有效的程序,但是一些JavaScript变量可能会改变类型"在一个程序的运行期间。那些你要么仍然需要实现变体,或者作为字符串(可以存储所有其他类型的相当低效的表示),然后使用{{1}样式的GetIntFromString()
函数进行转换我给的例子。
免责声明:所有代码都写在提交表单中,可能有拼写错误而且无法编译。
注意:另一种方法是do it like Smalltalk,其中变量通常是指向对象的指针,但是一些简单类型使用无效指针的值进行编码(例如奇数地址)大多数分配器都不会给你的,如果你的地址指向一个对象的开头,那么这是不可能的。)