mayankmahajan24 / QL

QL Language and Compiler, for Programming Langauges and Translators Course Fall 2015
4 stars 2 forks source link

Code gen skeleton #18

Closed mattpiccolella closed 8 years ago

mattpiccolella commented 8 years ago

So this pull request represents the final bridge of our compiler. Basically, it introduces a new type, jast.ml, which is our Java AST. To generate this, we essentially take our SAST, which consists of our AST plus our symbol table, and go, statement by statement, and convert them to our new node types. This converting is done in a file called semantic_to_jast.ml. Once we've converted, we pass the JAST, which is a list of JAST statements, and then "pretty-print" that, which yields our Java program. This pretty-printing is done in code_generator.ml, and represents the final step of our compiler.

Some notes:

1.) The JAST, at least so far, is almost identical to the AST - things like data type definitions (Literal_int) are very similar in both languages. The areas where we'll get differentiation are things like where and JSON - there has to be differentiation where there are not necessarily comparable constructs in the languages. I think it's fine that a lot of it is essentially copy-pasted - I believe it's important to see what stays the same - plus I don't think there's an opportunity for code reuse in this case.

2.) The way I generate code is essentially by passing a tuple of two things. The first thing is all the code contained in our main method. The second thing is all the functions we ever declare, which go outside the main method but are still declared in the class. Then, once all the statements have been handled, we just print them (as well as the headers) in the correct order. The code for this is pretty easy to understand. Also, in the header, I do a try for the overall main method, and then we can add all sorts of catch clauses for all the things that could conceivably go wrong in our program.

3.) I made two dummy types - Dummy_expr and Dummy_stmt - they're needed to make sure the tests pass. When we generate them, these just evaluate to empty strings, so they don't affect the output of the program. If nothing is being output by the thing you're implementing, it's probably getting caught by one of these.

So, what do we do now?

The way I'm doing it is essentially by adding a bunch of print statements to my code at all the different spots where we evaluate things. Then, I add the expected output - for example, if I have the expression print(5), I add 5 to the *-exp.out file for that given test. Then, once I get that test to pass, then the thing I was writing was implemented correctly. The tests I did this for were assign, array, hello, bool, and update_var. Y'all should take on some and work on them - function would probably be a smart way to continue.

Also, a small thing, but now when we compile, we pass a name of the file we want to compile to. So, we run qlc Test < test.ql.

Please comment on this, and let's aim to get in merged in ASAP.