您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何利用terralang實現terrapp”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何利用terralang實現terrapp”吧!
本文關鍵字:發明自己的語言,可lua擴展的語言系統,用庫發明語言vs用語言發明語言,是toolchain語言也是app生產語言,全生態語言
整個xaas系列文章中,我們編譯組裝了自己的dbcolinux,現在我們要發明自己的語言,如果說linux生態允許我們很大自由地定制一個完善的OS,那么terralang類似地,就是一個給我們定制語言系統的工具,它的設計目的之一就是這個,而且經過了專門的去復雜化。我們可以在少量知識和實踐儲備的前提下,copy-paste式地發明自己的簡單語言系統
我們要定制的語言系統是cpp ,在前面關于terralang的文章中《terracling》《terra++》,我們多次提到了這個目的,我們現在要利用terra最小核心實現一個真正可用的cpp —— 其實terra已經是個cpp了,但是它離真正可用的cpp還是有點差距,因為它只定義了最小語言擴展所需用到的核心(稍后談到它的正交類型和語句設計),所以嚴格來說它只是個cplus,而現在我們要在這個基礎上造一個接近標準CPP的dsl for terralang,terralang.org的網站中,也有大量相關資料專門提到這個專門課題,這成為我們的所有just enough起點。
在這之前,我們要了解terralang作為元語言工具的這種能力的深層原因,我們按前述文章的做法,稱呼 terralang為整個terralangsys,而terra是單個語言:
首先,terra應該被稱為terrac(Terra是c系的,terra is c extender towards Lua),但是它卻更適合被稱為terra/lua的,這是為什么呢,因為terralangsys中,terra被設計成與lua混編,那么terra究竟是發明語言的語言,還是用來被日常使用的語言。都可以,甚至terra當然也可以作為獨立語言(A scripting-language with high-performance extensions.....An embedded JIT-compiler for building languages.....A stand-alone low-level language....),但是大部分情況下,它以terra/lua方式被使用。lua中欠入terra---terralang主要用來metaprogramming或寫dsl。嚴格來說,terralang中只有terra,lua二種語言。
terralang中有二種獨立的語言,它們的runtime是并存的,也是可以離線分別使用的。Terra compiler is part of the Lua runtime,Terra executes in a separate environment: Terra code runs independently of the Lua runtime.在lua運行期對應terra的編譯期,而terra的運行期是OS的,并不綁定整個terralangsys
但是在語法上和使用上,terra/lua卻是一體的。甚至是緊密聯系的,就像一種語言——即terralang。
terra是用來代替和改進C的,它有自己的類型系統(Terra’s types are similar to C’s),代碼系統,和所有一門語言應該有的那些,本來如果C有terra需要的與lua交互的一切,那么C直接就是terra了,但是因為沒有,所以對C的增強就演化成了terra,——我們把它稱為cplus,在terra中日常編程是lua/terra混編,所以實際上可以視為lua/terra+cplus混編,另一方面,terra也是對lua的擴展,Terra expressions are an extension of the Lua language. The Terra C API extends Lua’s API with a set of Terra-specific functions,一句話,terra使lua像c,使c像lua
那么,為什么要這么做呢?因為terralang被設計成將C與lua良好交互,inter-operate,它必須要及其簡單,一開始就考慮進免binding交互,luajit有ffi可以以簡單的方式與C交互,其實luajit ffi對于C的封裝已經接近terra了,terra也是采用它的作法,既然Lua/c已經可以,為什么還要出一個terra/lua,這是因為其遠遠不夠。比如它缺少元編程和multiple stage programming那些,所以terra增進和增加了這些,它有哪些方面使得它一面像C,一面又接通lua
其實現原理和準則是什么呢?誠然多語言體系有極可能優秀的多的方案,但terralang只選取了適合自己的部分。
它實現了一個預處理器,使得設計期和執行期分離,Separating compile-time and runtime-time environments,這二個期,它們交互的單元非常小 —— 一個terra function或type這使得語言系統高效清希,二個期都有完備的語言系統,卻能承接,服務于一體化結果。這個過程是這樣的:
在設計期和編譯期,The preprocessor parses the text, building an AST for each Terra function. It then replaces the Terra function text with a call to specialize the Terra function in the local environment. This constructor takes as arguments the parsed AST, as well as a Lua closure that captures the local lexical environment. 使得在語法上,terra/lua是一體的。寫出來的.t程序將包含多語言源碼,但在編譯期shared lexical scope and different execution environments因為詞法作用域上,雙方的types彼此可見。隨時相互轉化。這種簡化是刻意而為之的:基于lua ffi,它使來自terra的所有語言元素作為lua的值存在,簡化了這二門語言在各個期的所有conversation,稍后會談到。
在運行期,it will call into an internal library that actually constructs and returns the specialized Terra function. The preprocessed code is then passed to the Lua interpreter to load. Terra code is compiled when a Terra function is typechecked the first time it is run. We use LLVM to compile Terra code since it can JIT-compile its intermediate representation directly to machine code. Clang is used to compile the C code into LLVM and generate Terra function wrappers that will invoke the C code when called.—— 最終在底層,combined terra/lua會是一堆lua和本地碼混合的東西,沒有terra的任何成份。compiler, generated code, and runtime of a DSL. 最終這三者都被打通形成一體語言。
這樣的努力帶來的效果就是——比起其它多語言系統,作為多語言免binding交互的典范,Terra and Lua represent one possible design for a two-language system.而其它元語言,如py的meta object,采用的并非語言控制語言,而是將這一切集成在單語言內,這樣不夠靈活也不夠強大-只有同時一門編譯語言一門腳本語言才能自然而然地兼有多語言的優點,比如llvm可以將性能關鍵部分生成為machine code保證性能。還有.net的clr封裝的unmanaged 模塊等。無一不帶天然缺陷。
下面詳細說下其中都有些東西,剛好的可互操作的類型正交系統,元編程能力,和multiple stage->DSL是一條因果路徑的。首先是其類型系統。
二門語言的交互,要看具體語言類型的是否typechecking屬性,作用域,生命期,內存布局這些。
在luajit的ffi時代就有這種思想,這也是lua的設計初衷———lua被設計成與c正交,user defined struct可以是一段C,既然有table,為什么不直接用它表達對象呢,有函數,為什么不能用它表達其它呢,這就是正交。terra對于c類型設計也是正交的,——— 所以,它是一種剛好設計語言的語言。不多不少,剛好正交。比如它的類型與C的那些很對應,比如它還有pointer,struct—它還加入了更多的面向metaprogramming stage programming的方面。比如,built-in tables that make it easy to manage structures like ASTs and graphs, which are frequently used in DSL transformations.
這種類型是用來作元編程的(至于要不要寫DSL那是另外一回事),Terra’s type system is a form of meta-object protocol,與其直接把類型設計為面向app生產,terralang的類型被設計成天然在某個staged compilation流程中被使用,這就是ecotype,它允許程序員—— 這里主要是元編程者或DSL發明者,在類型被具化之前,干預類型的內存布局行為等操作,
首先來看二門語言和各個期的typechecking。我們知道terra是需要的,lua并不需要,為了保證語言的一體化。就需要協調 - between compiler, generated code, and runtime of a DSL關于類型可能帶來的問題。In Terra (and reflected in Terra Core), we perform specialization eagerly (as soon as a Terra function or quotation is defined), while we perform typechecking and linking lazily (only when a function is called, or is referred to by another function being called). 這樣就可以規避矛盾的發生。
所以,terra的編譯期運行期分離,正交化設計的類型系統,都是為了簡化,變態簡化,只是為了最終使DSL的發明更簡單一點。最后的重頭戲來了,這就是共享詞法域,它是服務于讓terra寫dsl變態簡化的另外一個方面。
下面來說這個共享詞法作用域,它最終使分離的東西在語法層形成一門叫terralang的東西。去除了在傳統stage programming放置操作符(quotation,escape,etc..)的需求。這里需要結合terralang的生成代碼機制和元編程機制講,我們還沒有談到terralang的生成代碼的機制,上面只是粗略提到,總而言之,從語法到最終語言形態上,二種共存的語言要處理的問題不可繞過(between compiler, generated code, and runtime of a DSL)作用域就是一方面,The shared lexical environment makes it possible to organize Terra functions in the Lua environment, and refer to them directly from Terra code without explicit escape expressions. 甚至去除了namespace的調用需要。To further reduce the need for escape expressions, we also treat lookups into nested Lua tables of the form x.id1.id2...idn (where id1...idn are valid entries in nested Lua tables) as if they were escaped. This syntactic sugar allows Terra code to refer to functions organized into Lua tables (e.g., std.malloc), removing the need for an explicit namespace mechanism in Terra.
對于作用域,在staging的各個階段和形態上并同時透明地跨越lua,terra,都保持了正交。這樣本節開頭提到的關于類型的矛盾,就都解決了。而且我們始終要記住:變態簡化是設計一開始就maintain的原則。
下面來綜合講述metaprogramming到DSL的原理。
其實元編程不一定DSL,我們可以僅使用terralang作meta programming。這也是大部分情況下我們使用terralang的情景。這節標題中的元編程可以放到前一標是,只是terralang的元編程更適合寫DSL而已,與后者結合更為增益。
在前面說過,其實無論那種語言,寫代碼都是擴展語言寫“DSL”,庫也是語言的擴展。----- 要么面向問題要么面向擴展語言本身要么面向APP,只是terralang使得這種DSL具現化。
多種語言有多種元化代碼生成的手段,CPP是基于模板的— 它就是一種編譯期的類型特化過程,,還有跨語言元化的,這就是stage programming,在stage programming的范籌里,有一些生成操作符,上面寵統描述terralang的元編程技術中也有提到過。
為動態運行期生成代碼的能力。這相當于cpp template programming的多語言版本。雖然terralang是真真實實地使用llvm,而不是同樣圖靈完備的基于template技術的CPP實現———。但這二者很類似,這2個過程可以類比。
前面的類型正交設計和共享詞法域已經為terra做了大部分工作。ease這里的復雜度也許只是關于DSL本身的。我們知道,如果一旦涉及到編譯原理,就很復雜,這里的復雜度幾乎減無可減,因為涉及到數據結構,詞法分析,遞交等系統編程,但terralang也有自己的方案,它用了一種叫Pratt Parsers的方法,What makes this parsing technique interesting is that the syntax is defined in terms of tokens instead of grammar rules,再加上terralang也會專門性地提供一些造語言的API,極大簡化了發明DSL的難度。這些發明出來的dsl作為terra的模塊存在。并非欠入terra,而是欠入到lua。
這就是說,為terralang擴展DSL,做法上也很簡單,完全去除了需要專門發明詞法解析器等語言設施的需求。雖然它使用了編譯原理,但是它使用的是更有限更簡單的有限集,因為所有語言的區別只是一些對于terralang的入口table。
Terralang的DSL能力尤為珍貴,因為它允許任何人發明語言,terra擴展語言本來就設計成要開放成給任何人使用。
——————
Terra是為c系增加一門scripting的最佳實踐。它把c改造為Lua like,也把lua/terra,改造為c like scripting,當然它的主要作用在于發明DSL,—— 以后,我們可以在這個c/terra上發展cpp,除了擁有一個全態全包的語言體系,甚至還能有一個高性能的庫Terra’s type reflection allows the creation of class-systems as libraries。
Terra,,the programmable cp with Lua,,just like programmable nginx with Lua,有了terralang,從此什么語言都有了,terralang既是app生產語言,又是toolchain語言。還是shell語言,makefile語言等
感謝各位的閱讀,以上就是“如何利用terralang實現terrapp”的內容了,經過本文的學習后,相信大家對如何利用terralang實現terrapp這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。