lang:自制編程語言16——變量棧

前言

完善一些細節,爲最後一個function的功能添磚加瓦。實現了局部變量後,還有實現變量的local聲明、const聲明……


命名行運行suatin.exe

 E:\ 的目錄

2020/03/04  23:14    <DIR>          Can
2020/01/22  00:00    <DIR>          File
2020/03/05  19:41    <DIR>          JSP
2020/03/27  00:28                 6 main.suatin
2020/03/24  17:54    <DIR>          SQL
2020/03/27  00:30         1,038,336 suatin.exe
2020/03/10  11:49            48,935 test.jpg
2020/02/26  16:24    <DIR>          VSCode Used
2019/11/30  04:36    <DIR>          視覺小說企劃
               3 個文件      1,087,277 字節
               6 個目錄 12,275,941,376 可用字節

E:\>suatin

E:\>E:\suatin.exe test.jpg
文件不是suatin類型文件

E:\>E:\suatin.exe main.jpg
文件不是suatin類型文件

E:\>E:\suatin.exe main.suatin
[0]普通語句>sum=0;
[0][result]0
suatin environment>
                name   isconst    type      funcPtr     flag             num   str
                 NIL    true       nil     00000000    false               0
               FALSE    true      bool     00000000    false               0
                TRUE    true      bool     00000000     true               0
                 sum   false    number     00000000     true               0
program time consumed 73 ms

E:\>
//main.cpp
#include"Resolver.h"
int main(int argc, char *argv[]){

	if (argc < 2) {//參數不夠
		return 1;
	}

	std::string s = argv[1];
	std::string suffixStr =s.substr(s.find_last_of('.') + 1);//獲取文件後綴
	if (suffixStr != "suatin") {
		std::cout << "文件不是suatin類型文件" << std::endl;
		//system("pause");
		return 1;
	}

	sua::g_file_dir = argv[1];//獲取文件路徑

	time_t start = clock();

	////初始化環境
	//SHOWFUNCTIME("初始化語言環境", sua::InitEnv);
	sua::InitEnv();



	//sua::g_file_dir = "main.suatin";
	//詞法分析
	//SHOWFUNCTIME("詞法分析", sua::Lexer);
	sua::Lexer();
	//顯示全局中綴表達式
	//SHOWFUNCTIME("全局中綴表達式", sua::ShowGlobalInfix);

	////語法分析
	sua::Resolver  p;
	//SHOWFUNCTIME("語法分析·創建語法樹", p.create);
	p.create();
	//SHOWFUNCTIME("語法分析·打印語法樹", p.print_ast);
	//p.print_ast();
	//p.print_st();
	//SHOWFUNCTIME("語法分析·解釋語法樹", p.interpret);
	p.interpret();

	//顯示環境信息
	//SHOWFUNCTIME("顯示環境信息",sua::PrintEnvInfo);
	sua::PrintEnvInfo();
	
	//釋放環境
	//SHOWFUNCTIME("釋放環境", sua::FreeEnvSpace);
	sua::FreeEnv();
	std::cout << "program time consumed " << clock() - start <<" ms" <<std::endl;
	//system("pause");
	return 0;
}

精簡ID內存結構

看上一篇文章lang:自制編程語言15.5——C++如何在struct中使用union???
15.5這篇文章中,我將flag\num\str幾個的屬性結構體改成了共用體了!!!其中str的長度和其他幾個變量沒法比,單單是string這個類型都有28個字節,所以我把str屬性換成了str指針!!!

還剩下一個isconst屬性,這個屬性也可以去掉。
在語言環境(符號表)中設置一個常量區,只要檢查這個變量是否在常量區就行了,常量區不一定是全局的,每一個scope下都可以有一個常量區(也許這樣查找的時間複雜度就上來了2333)

CSDN
https://download.csdn.net/download/weixin_41374099/12278652
BDWP
鏈接:https://pan.baidu.com/s/1Rc1BntnKyh0d0aDwXZXqOw
提取碼:3pt0

設計變量棧

設計變量棧是爲了實現局部變量。爲此需要區分這樣四條語句。

  1. x; 表示定義全局變量或本地變量(當然,因爲是nil類型,解釋時肯定是出錯的)
  2. local x; 表示定義全局變量或本地變量,這個語句存在的位置不做要求
  3. const x; 表示定義常量,常量不區分是全局還是本地
  4. del x; 表示刪除某條語句,如果這條語句在本地的就刪除本地,如果在全局就刪除全局的。如果是常量,就刪除常量——如果不存在此變量,不報錯!
	/*語言環境
		由一個棧組成!
		棧底scope=0是特殊變量區(關鍵字NIL、TRUE、FALSE就是特殊變量)
		scope=1是常量區
		scope=2是全局變量區
		scope>2是局部變量區
	*/
	typedef std::map<std::string, SuatinID*> _SuatinVar_Scope_Unit;
	typedef  std::vector<_SuatinVar_Scope_Unit*> _SuatinVar_Stack;
	extern _SuatinVar_Stack  SuatinEnv;

項目演示
//test.suatin
sum = 0;
for(i=0;i<120;i=i+1)
	if(i>=45)
		sum = sum + i;
	end
end
...
...
...
[2][result]true
[4][result]true
[5][result]6031
[3][result]119
[2][result]true
[4][result]true
[5][result]6150
[3][result]120
[2][result]false
suatin environment>
------------------------------------------------------------------------------
                 name     type    value
scope=0_[special variable zone]>
                  NIL      nil    false
                FALSE     bool    false
                 TRUE     bool    true
scope=1_[const variable zone]>
scope=2_[global variable zone]>
                    i   number    120
                  sum   number    6150
------------------------------------------------------------------------------
program time consumed 2674 ms
請按任意鍵繼續. . .

這次畫的時間頗多了。。。。沒學知識只能靠奇技淫巧,這就是看不懂編譯原理的代價。。。。快點做完function就去學編譯原理啦!

CSDN
https://download.csdn.net/download/weixin_41374099/12304911

BDWP
鏈接:https://pan.baidu.com/s/1K23mufEgCimVty2XWw-mDg
提取碼:name

識別local x;const x;del x;

完善變量棧

結束了,不做了

function功能不要了,項目越來越爛,已經不想做下去了。Debug模式下,一萬個數的空循環運行消耗從一秒變成了4秒!

因爲語言環境的複雜性,導致變量查找和確認消耗大量時間。比如之前的項目中,我用了二十多個if來判斷字符串是什麼關鍵字,爲什麼不用哈希查找呢?明明哈希只用一次就找到了,不用執行多次——原因是字符串轉哈希值太浪費時間了,項目中現在的語言環境也是通過字符串求哈希值再找到變量的——

寫了一堆垃圾代碼,項目結構也亂七八糟,好多東西都是打的補丁,真出錯了連自己也不知道。不知道具體錯誤這一點呢,因爲異常太難捕獲了,自己設計的打印異常信息的機制也不完善,很多地方出了錯也不知道位置,錯誤信息與錯匹配不上!

計算都是double數據,int數據做了兩個多月也沒使用過!

解釋接口不止一個!

不能計算大數!就比如222222222222222222222222222222222x33333333333333333333333333這樣的就計算不了!

Parser只能處理簡單的語句,導致重複的結構又在Resolver裏寫了一遍!

源碼的掃描不止一遍,浪費了時間!

詞法分析全扔給正則了,鬼知道實際對源碼掃描了幾遍!

語言拋異常也無法定位到準確的行數,或者說根本沒有行數的概念!

語法分析用的相當愚蠢的方法,每次遇到一個Token就更改一下語法樹!這也是因爲不會遞歸!

現在還沒做出函數的功能!單單用後綴表達式的話,在計算機改進版那篇文章裏我已經實現了幾十個函數的使用了!

  • 另外說一句,感覺語言的確做出來,雖然很簡單但是的確做出來了。比兩個月以前想要的功能更豐富一點,可是一點成就感也沒有。

這是Suatin編程語言項目目前所有的記錄了:
鏈接:https://pan.baidu.com/s/1ErD6-8pcQN01c4LQFiE7bA
提取碼:58h1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章