jzimmerman / langcc

langcc: A Next-Generation Compiler Compiler
https://langcc.io
Apache License 2.0
1.73k stars 58 forks source link

How to create an instruction to print a variable ? #20

Closed aatomium closed 2 years ago

aatomium commented 2 years ago

All is in the title.

jzimmerman commented 2 years ago

Could you say a bit more about what you're trying to do? Are you trying to print a variable from C++ (i.e., logging), or do you have a "Variable" AST node in your language that you're trying to print? (Or something else?)

logicReasoner commented 2 years ago

I believe that they meant the latter case, i.e. how to define a print statement definition in the .lang file. But now that you mention it, please show an example of how do you print a variable from C++ (i.e., logging).

jzimmerman commented 2 years ago

I'll try to answer both questions. To create a print statement in your language, you need to define BNF for what you want that print statement to look like. For instance, in the calculator example (examples/calc.lang), you might define a parser rule as follows:

Stmt.Print <- `print` `(` x:Expr `)`;

where print is defined as a new keyword token in the lexer:

id <- `a`..`z` (`a`..`z` | `0`..`9`)* - kw;
kw <= `print`;
int_lit <- `0` | `1`..`9` (`0`..`9`)*;
top <= id | int_lit | `+` | `-` | `*` | `/` | `^` | `=` | `(` | `)` | kw;

To print a variable from C++, you can write:

LG("x = {}, y = {}", x, y);

to log unconditionally to stderr, or:

LOG(lvl, "x = {}, y = {}", x, y);

to log at a specific level lvl. Please note that in order for this machinery to work properly, you will need to run:

global_init();
set_log_level(n);

at the start of your main function. Also, in order to be printable in this fashion, the variables x and y need to have pr(ostream&, FmtFlags, T) defined for the relevant type T; you can find many examples of this in src/langcc_util.hpp.

In particular, AST nodes do not come with pr defined by default; this is a deliberate choice, as you may have some notion of "printing" an AST node other than pretty-printing its syntax. You are free to make a specific choice in your code, such as:

void pr(ostream& os, FmtFlags flags, lang::mylang::Node_T x) {
    pr_debug(os, flags, x);
}

or:

void pr(ostream& os, FmtFlags flags, lang::mylang::Node_T x) {
    x->write(os, flags);
}
logicReasoner commented 2 years ago

This more than explains what has been asked. Thank you! If it was up to me, I'd close the issue right away!