Age | Commit message (Collapse) | Author |
|
Until now the below code was not valid for pipac.
fn main(): i32 {
return fib(13);
}
fn fib(n: i32): i32 {
if n <= 1 {
return n;
}
return fib(n - 1) + fib(n - 2);
}
Pipa's parser was adding a function to scope after they were fully
parsed which means that fib's self-reference would not work.
Also, functions were required to follow the be called in the order they
are declared for the same scope reason so, the main function was
required to be defined after fib.
And how it is working now?
When a TOKEN_NAME is not found in the scope, instead of returning an
error, an unknown token is created as placeholder. The parser stores the
node reference and the token it was trying to parse.
During type checks, if the parser detects an unknown node, instead of
returning an error, it stores in that node what was the expected type.
After the NS is fully parsed a reevaluation is made on those unknown
nodes by setting the lexer back on the node's token position and parsing
the TOKEN_NAME again.
Ps: There is a typo on the unknown token. It will be addressed in
another commit since this issue was not introduced by this change.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
|
|
We have been always parsing a single function. Since we want to have
multiple functions in a near future, this patch introduces an namespace
that represents an entire file.
To ensure a function is defined inside a namespace, a helper function
was created. Today our ast_node structure is highly exposed, and this is
something that Johnny and I have been discussed. So then, this is a
first step to try to protected the code generation from our ast tree.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
|
|
Signed-off-by: Carlos Maniero <carlos@maniero.me>
|
|
In many situations, the parser is responsible for reserving memory for
nodes, particularly during function body parsing. This commit introduces
a new standard where parser functions not only allocate memory for
ast_nodes, but also return them. In case of a parser error, a NULL
pointer is returned.
This standard will be extended to other parsers in future commits,
ensuring consistency throughout the codebase.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
|
|
We are parsing variables/functions and checking if they are defined on
scope. Otherwise we fail the parsing with a nice message.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
Co-authored-by: Carlos Maniero <carlosmaniero@gmail.com>
|
|
We want to keep the code style consistent, this first commit adds a
.clang-format in order to "document" our style code.
This patch also adds a target *linter* to Makefile which will complain
if we have any style issue on test and src dirs.
I have run the follow command to create the .clang-format file:
$ clang-format -style=mozilla -dump-config > .clang-format
And I also made some adjusts to .clang-format changing the following
properties:
PointerAlignment: Right
ColumnLimit: 120
Commands executed to fix the current styling:
$ find . -name *.h | xargs clang-format -i
$ find . -name *.c | xargs clang-format -i
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
|
|
This commit adds support for variables and identifiers in the function
body of the parser, stored as a vector.
However, at this point, identifier resolution is not fully implemented,
and we currently accept identifiers without checking if they can be
resolved. This is a known limitation that will be addressed in a future
commit once hash-tables are added to the parser.
Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com>
Reviewed-by: Johnny Richard <johnny@johnnyrichard.com>
|
|
This patch implements the AST creation for arithmetic expressions.
NOTE:
The implementation works only for integer numbers.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
Reviewed-by: Carlos Maniero <carlosmaniero@gmail.com>
|
|
Previously, when an error occurred during parsing, the application
would exit, making it difficult to test the parser and limiting the
compiler's extensibility. This commit improves the parser's error
handling by allowing for continued execution after an error, enabling
easier testing and increased flexibility.
The parser is prepared to handle multiples errors, although the
current implementation always returns a single error, it may be
useful given multiples functions where we can show errors by context.
Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com>
Reviwed-by: Johnny Richard <johnny@johnnyrichard.com>
|
|
Previously, the abstract syntax tree (AST) used static types, meaning
that an ast_function_t would always have a ast_return_stmt_t as
its body. However, this assumption is not always true, as we may have
void functions that do not have a return statement. Additionally, the
ast_return_stmt_t always had a number associated with it, but this too
is not always the case.
To make this possible, I need to perform a few changes in the whole
project. One of the main changes is that there is no longer the
inheritance hack. That mechanism was replaced by composition and
pointers where required for recursive type reference.
It is important to mention that I decided to use union type to implement
the composition. There is two main advantages in this approach:
1. There is only one function to allocate memory for all kind of nodes.
2. There is no need to cast the data.
In summary, this commit introduces changes to support dynamic typing
in the AST, by replacing the inheritance hack with composition and
using union types to simplify memory allocation and type casting.
Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com>
Reviewed-by: Johnny Richard <johnny@johnnyrichard.com>
|
|
In the future we want to have the possibility of traverse the tree and
pretty print it or generate binary for other platform like LLVM or
transpile to C.
This solution also implements the gas assembly x86_64 Linux code
generation by using the visitor interface.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
|
|
This change fixes the memory leak when token got created.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
|
|
This is a very limited parser implementation which parses a single
function with return type i32 and body containing a return number statement.
The parser doesn't show the 'filepath:row:col' when it fails, a future
improvement would be display it to easy find where the compilation
problem is located.
The ast_nodes are taking the token.value ownership (which is a really
bad design since not all token.value ownership has been taken causing
memory leaking) but we never free them. For a future fix we could use a
string_view instead since we never change the original source code. The
string_view will also improve the performance a lot avoiding unnecessary
heap memory allocation.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
|