Lucida-a function Program The birth of Design Language
Cause
I want to writeProgramming LanguageBut it will lack the compilation skills. After reading DSL and language implementation patterns and writing a certain number of parser, I have a comprehensive understanding of compilation, you may also want to understand the operating mechanism and implementation process of a language. And now I have used a lot of languages, including C, Oo, C ++, C #, Java, and JavaScript and python, there are scheme and Haskell functions, and the number of books read is even more numerous, so that later I felt boring.
Now, many people are keen on functional programming languages such as F # And scala. To tell the truth, it is better to write them by yourself instead of learning these things, that is much more profound than learning these things. I don't want to pursue reinvent the wheels. I just think there are too many wheels. I can't finish learning it after I finish learning it. Instead of getting confused by these things, you may wish to get a new one. In the future, nothing new will be caught off guard.
Design
After a short thought, I decided to build a functional programming language in the shortest time based on scheme, Haskell, and python to support all the basic features of functional programming. In addition, I need to provide an easy-to-use interactive interface for this language, just like ghci or idle.
To facilitate the construction of the parser, I almost did not hesitate to choose the scheme RPN (reverse polish expression) syntax, although this syntax is somewhat strange:
(DEF (f a) (* ))
(F 3) => 9
With the scheme reference, the lexical analyzer and syntax analyzer of the build language are quite simple. It took less than two hours to get tokenizer and parser, and the front-end part is done.
BecauseCodeI am not familiar with generation. What I Want To Get is an interpreted language, so it is enough to have an intermediate structure. Here I use the heterogeneous abstract syntax tree that I am familiar: you can use a base node to export child nodes of various functions. At the same time, child nodes can save references to the base node. in simple words, they are composite pattern.
The commonly used syntax structure does not matter the definition, the reference, the call function, and the branch statement, you only need to follow the BNF written one by one to calculate the time for designing the object model on the draft paper, it took me more than an hour.
The next step is the type system. To make the first prototype as soon as possible, I have selected four basic types: Number, list, function ), name ).
The number naturally saves an integer. It is easy to use the int64 provided by CLR.
It took me some time to design the list, mainly to choose between the homogeneous list (Haskell style) and the heterogeneous list (Python style), but think of the homogeneous list to do the work of Type derivation, I chose a simpler heterogeneous list (and the feature seems to be more powerful, but I cannot provide static type checks ).
Since functions in functional languages can also be passed as values, you do not need to name them. You only need to set their form parameters and method bodies. Here, its method body is a syntax tree. to execute this function is to replace the real parameters in the syntax tree and then define the results. Naturally.
The name is the name of the above Type instance. The name stores a reference to the base type, so it can point to any type, so that the function assignment is very simple, for example:
This part took a long time and took about three hours, because it overthrew several unreliable designs and took some time.
The next step is the outermost interpreter. Here we use the mode of commonly used explanatory languages: Read and Eval: first, read the code with read to perform a simple syntax check. Then the eval executes the code (in fact, it is to convert the idiom tree and specify the result), and then outputs the result on the console. No design is required here, it took some time to set the color of the console. I have always been uncomfortable with the ghci or idle color scheme, so I will never let the color scheme of my own interpreter be as bad as they are:
After a few simple tests, I got the symbol table and tested it. Variable assignment and function recursion can be used. There are some problems with list recursion. After reading the time, it has been taking a rest for almost 10 hours. It took nearly two hours to pull out the bug the next morning. It turned out that some memory references were shared when the function was used to generate a list, so it would be nice to modify it. I again experienced the nausea of debugging.
The next step is to introduce basic operations. This is simple: Write a predefined method table, and then the corresponding methods in the specific operator callback method table. I have used this method before, so it takes almost no time to complete the afternoon, Arithmetic Operators, logical operators, and basic list operations, after dinner, I wrote three common high-level functions: map, reduce, and filter. Anyone who has played functional programming or Python knows the role of these functions, which is not very useful.
I have always liked Haskell and Python's list comprehension, so I tried to get it in. But considering the limitations of RPN syntax, I referred to the range Function of Python, to quickly generate a list.
Again, because they are all obvious things, nothing can be wrong.
In fact, lucida has become a full-featured language: Variable assignment, recursion, list, high-level functions, and common built-in functions, as a language, there are several basics.
I used to think that writing a language is a very troublesome task, but it is actually nothing after writing it,Anyway, who cocould not design and implement a programming language inTwoDays?
Next work
Introduce the floating-point type and the mixed operation of floating-point type and integer type:
Introduce anonymous functions and curry functions:
Introduce character and string types and design conversion between them and list and number:
Add some interesting attributes to the operator:
Set operator ing to write extremely short code:
The last step is to write a language manual. This is better to write, just like K & R's C programming language. If you are interested, you can download and read at this link.
Postscript
In this review, lucida is basically complete from nothing to prototype, that is, less than a week. So here we suggest that students who want to learn new languages stop,Spend time writing a language by yourself, which is more profound than learning a language.Besides, it takes little time to write a small language.
I just saw a compilation-related blog in the jar. The blogger seems to be calling the Assembly head (Strange name ), he has already made it very clear to compile common things. It is not a problem to write a language carefully. Unfortunately, most of the replies I have seen are not nutritious, but they are meaningless.
Anyway, that's all. If you are interested, you can exchange programming language knowledge: lunageek@gmail.com