update readme:difference between this and andy's interpreter

This commit is contained in:
ValKmjolnir 2021-08-01 01:54:14 +08:00
parent aa797142d1
commit df634cb1b2
3 changed files with 71 additions and 15 deletions

View File

@ -774,3 +774,56 @@ nasal_val* builtin_keys(std::vector<nasal_val*>& local_scope,nasal_gc& gc)
return ret_addr;
}
```
## Difference Between Andy's Nasal Interpreter and This Interpreter
This interpreter uses more strict syntax to make sure it is easier for you to program and debug.
In Andy's interpreter:
```javascript
foreach(i;[0,1,2,3])
print(i)
```
This program can run normally with output 0 1 2 3.
But take a look at the iterator 'i',this symbol is defined in foreach without using keyword 'var'.
I think this design will make programmers filling confused.
This is ambiguous that programmers maybe difficult to find the 'i' is defined here.
Without 'var',programmers may think this 'i' is defined anywhere else.
So in this new interpreter i use a more strict syntax to force users to use 'var' to define iterator of forindex and foreach.
If you forget to add the keyword 'var', and you haven't defined this symbol before, you will get this:
```javascript
>> [code] line 1: undefined symbol "i".
>> [codegen] in <"test.nas">: error(s) occurred,stop.
```
Also there's another difference.
In Andy's interpreter:
```javascript
var a=func {print(b);}
var b=1;
a();
```
This program runs normally with output 1.
But in this new interpreter, it will get:
```javascript
>> [code] line 1: undefined symbol "b".
>> [codegen] in <"test.nas">: error(s) occurred,stop.
```
This difference is caused by different kinds of ways of lexical analysis.
In most script language interpreters, they use dynamic analysis to check if this symbol is defined yet.
However, this kind of analysis is at the cost of lower efficiency.
To make sure the interpreter runs at higher efficiency, i choose static analysis to manage the memory space of each symbol.
By this way, runtime will never need to check if a symbol exists or not.
But this causes a difference.
You will get an error of 'undefined symbol', instead of nothing happening in most script language interpreters.
This change is __controversial__ among FGPRC's members.
So maybe in the future i will use dynamic analysis again to cater to the habits of senior programmers.

View File

@ -18,20 +18,23 @@ void help_cmd()
#ifdef _WIN32
<<"use command \'chcp 65001\' if want to use unicode.\n"
#endif
<<"nasal | use interactive interpreter.\n"
<<"nasal -h, --help | get help.\n"
<<"nasal -v, --version | get version of nasal interpreter.\n"
<<"nasal filename | execute script file.\n";
<<"nasal [option]|[file]\n"
<<" input 0 argument to use the interactive interpreter.\n"
<<"option:\n"
<<" -h, --help | get help.\n"
<<" -v, --version | get version of nasal interpreter.\n"
<<"file:\n"
<<" input file name to execute script file.\n";
return;
}
void info()
{
std::cout
<<">> Thanks to https://github.com/andyross/nasal\n"
<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<">> Code: https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<">> Info: http://wiki.flightgear.org/Nasal_scripting_language\n"
<<">> Input \"help\" to get help .\n";
<<">> thanks to https://github.com/andyross/nasal\n"
<<">> code: https://github.com/ValKmjolnir/Nasal-Interpreter\n"
<<">> code: https://gitee.com/valkmjolnir/Nasal-Interpreter\n"
<<">> info: http://wiki.flightgear.org/Nasal_scripting_language\n"
<<">> input \"help\" to get help .\n";
return;
}
void logo()
@ -42,7 +45,7 @@ void logo()
<<" / \\/ / _` / __|/ _` | | \n"
<<" / /\\ / (_| \\__ \\ (_| | | \n"
<<" \\_\\ \\/ \\__,_|___/\\__,_|_|\n"
<<" Nasal interpreter ver 7.0 \n";
<<" nasal interpreter ver 7.0 \n";
return;
}
void die(const char* stage,std::string& filename)

View File

@ -80,8 +80,8 @@ nasal_ast::nasal_ast(const nasal_ast& tmp)
{
line=tmp.line;
type=tmp.type;
str =tmp.str;
num =tmp.num;
str =tmp.str;
children=tmp.children;
return;
}
@ -90,8 +90,8 @@ nasal_ast::nasal_ast(nasal_ast&& tmp)
{
line=tmp.line;
type=tmp.type;
str.swap(tmp.str);
num =tmp.num;
str.swap(tmp.str);
children.swap(tmp.children);
return;
}
@ -100,8 +100,8 @@ nasal_ast& nasal_ast::operator=(const nasal_ast& tmp)
{
line=tmp.line;
type=tmp.type;
str=tmp.str;
num=tmp.num;
str=tmp.str;
children=tmp.children;
return *this;
}
@ -110,8 +110,8 @@ nasal_ast& nasal_ast::operator=(nasal_ast&& tmp)
{
line=tmp.line;
type=tmp.type;
str.swap(tmp.str);
num=tmp.num;
str.swap(tmp.str);
children.swap(tmp.children);
return *this;
}
@ -119,8 +119,8 @@ nasal_ast& nasal_ast::operator=(nasal_ast&& tmp)
void nasal_ast::clear()
{
line=0;
str="";
num=0;
str="";
type=ast_null;
children.clear();
return;