2010-04-03 16 views
0

我已经为C++中的一种愚蠢的编程语言创建了一个解释器,并且完成了整个核心结构(Tokenizer,解析器,解释器包括符号表,核心函数等)。以编程语言管理库和导入

现在我有创建和管理的函数库这一解释的一个问题(我会解释我的意思与更高版本)

所以目前我的核心功能处理程序是可怕

// Simplified version 
myLangResult SystemFunction(name, argc, argv) 
{ 
     if (name == "print") 
     { 
     if(argc < 1) 
     { 
      Error('blah'); 
     } 
     cout << argv[ 0 ]; 
     } else if (name == "input") { 
     if(argc < 1) 
     { 
      Error('blah'); 
     } 
     string res; 
     getline(cin, res); 
     SetVariable(argv[ 0 ], res); 
     } else if (name == "exit) { 
     exit(0); 
} 

现在想起其他每个人,如果是10倍更复杂,并有25个以上的系统功能。难以维护,感觉可怕,太可怕了。

所以我想:如何创建一些类库包含所有的功能,如果他们进口初始化自己并将其功能添加到正在运行的解释器的符号表。

然而,这是我真的不知道该怎么去的地步。

我想达到什么是有如:一个(EXTERN?)字符串库对我的语言,如:字符串,它是在程序中使用该语言,例如输入:

import string 
myString = "abcde" 
print string.at(myString, 2) # output: c 

我的问题:

  • 如何独立于核心解释函数库并加载它们?
  • 如何将所有函数放入列表并在需要时将其添加到符号表中?

我在想什么做的事:

在翻译开始,所有图书馆都用它编写,每一个函数调用类似RegisterFunction(string namespace, myLangResult (*functionPtr));它增加了自己的列表。然后在语言中调用import X时,用RegisterFunction构建的列表将添加到符号表中。

缺点映入脑海:

所有图书馆都直接在解释核心,规模的增长,它肯定会减慢车速。

回答

1

如果您的解释器是作为库实现的,它将从其他人的C++代码中调用。他们必须从自己的代码中调用库中的函数来为解释器添加函数,这并非不合理。这是我自己的表达评估者所做的。像这样的用户代码:

Interpreter in; // an instance of the interpreter 
in.AddFunc(lenfun, "length", 1); 
in.AddFunc(catfun, "concat", 2); 

在调用者必须提供一个指向执行功能,并为功能参数的名称和编号。这适用于无类型的设置 - 如果你严格打字,当然还有很多工作要做。

1

我认为你应该看看Command模式。然后,您可以将每个函数实现为Command并具有一个将函数名称映射到Command对象的映射。

通过让每个库都有一个初始化函数,它将函数添加到地图中,这也将使您能够从外部库加载附加函数。

0

目前还不清楚你是否瞄准了功能齐全的编程语言,或者如果这是一个玩具,所以我不知道你想投入多少时间。我怀疑动态库加载会比你需要的复杂得多。您可能需要一个PATH库位置列表,或者您需要注册名称空间 - 这会让您回到现在的相同位置。

一个更简单的方法是保留一个全局符号表和相关的处理程序。

使用std :: map(或hash_map)比if/else构造更快速地查找函数。让所有函数用符号表注册。

存储在符号表中的“处理程序”可以是简单的对象(或函数指针),并可以进行自己的参数检查。

class FuncHandler { 
    virtual MyLangResult Run(argv, argc) = 0; 
} 

typedef std::map<string, FuncHandler*> FuncTableType; 

// Simplified version 
myLangResult SystemFunction(name, argc, argv) 
{ 
    FuncTableType::const_iterator it = function_table_.find(name); 
    if (it == function_table_.end()) return Error("Unknown function: " + name); 
    return it->second(argc, argv); 
} 

我写了一些代码来执行自我注册为这个问题类,但它并不一定需要在这里: Accessing C++ Functions From Text storage