| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
| |
There's also a `run.sh2` script which does the following:
- Compiles the C compiler `build/cupcc`
- Compiles the self-hosted compiler `build/cup.out` (with `cupcc`)
- Compiles the specified file on CLI with `build/cup.out`
- Runs this exectuable and shows the output
|
| | |
|
| |
|
|
|
| |
(1) Add support for escaped single quotes
(2) Fix `putu_buffer` in `std/common.cup`
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
Turns out they're supposed to be accessed on the stack there. For
macOS, because 16 byte-alignment is "required", we don't know the
exact position of the arguments and that they're also passed in
through `rdi` and `rsi`
|
| | |
|
| | |
|
| |
|
|
|
|
| |
- `close()` syscall
- `putu_buffer()`
- toy `malloc()` which can allocate from a 1gb pool without freeing.
|
| | |
|
| |
|
|
| |
The code to initialize them is put right before calling `main()`
|
| | |
|
| |
|
|
|
|
| |
We can now directly expose the `syscallN()` APIs to the program and
define the `open()`, `write()` etc syscalls in the stdlib. This
simplifies the implementation a decent bunch :^)
|
| | |
|
| |
|
|
|
|
| |
Basically, it looks like an enum but it isn't actually a type. It
just behaves like a container to number all the (global) constants
defined within it.
|
| |
|
|
|
|
| |
(1) Return correct size for unions
(2) Make sure function name identifier doesn't exist
(3) Assign `<anonymous>` as display name for nested compound types
|
| | |
|
| |
|
|
|
| |
We don't use absolute paths or anything fancy right now, but it's
a basic prototype which can be extended upon.
|
| |
|
|
|
|
|
| |
We can now have constant definitions that are read-only, evaluated
at compile time and just behave like integer literals when accessed.
These are nice because we can now potentially inject syscall numbers/
etc through the compiler.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
This was simple enough, we just needed to change the part where we
were computing the offset for each field, and the total size of the
compound structure.
|
| |
|
|
|
|
|
|
| |
Structs for now (and probably for the near future) are not allowed
to be passed by value, and instead you just pass a pointer to it.
Nested structs can also be defined, and they can be either anonymous,
or named (in which case only the members can access the type).
|
| |
|
|
|
|
| |
If we know the type of the expression on the RHS, and no type is
specified, then we can just assume that the variable has the same
type.
|
| |
|
|
|
|
| |
The implementation is very hacky, maybe there's a better way to go
about doing this. Maybe just keep it as single AST node and do the
work during codegen?
|
| |
|
|
|
| |
Now we can have variable declarations as part of the initialization
of the for loop, and it can only be accessed within the loop.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
This was possible, but very tedious to do by hand before. Now we
automate it based on the number of arguments.
Note that currently we can't just add `syscall3()` etc as builtins
because the actual numbers for the system calls vary from one system
to another, and we want to maintain support for macOS and Linux (at
least for now).
|
| |
|
|
| |
Since we allow implicit conversions now the exact type is less relevant.
|
| |
|
|
|
| |
`putc`, `puts`, and `putnum` in `std/common.cup` are now implemented
in terms of the `write()` syscall.
|
| |
|
|
|
| |
Probably want to add more builtins in the future, so pulling it out
of `parser.c` seems like the reasonable thing to do
|
| |
|
|
| |
This design should also be useful for structs down the road.
|
| |
|
|
|
|
| |
In the future we can split this into multiple files if we need to,
after we've added to ability to handle more complex input graphs without
parsing the same file twice.
|
| |
|
|
| |
Simple optimization, it was just adding extra overhead anyway.
|
| |
|
|
|
|
|
|
|
|
|
| |
This commit does a few things in one go:
- Add support for a `char` type + some changes to support the new size
- Add support for character literals. We need some escaping here to be
able to use `\n` and `\0`, etc.
- Add support for string literals. These are all stored in the `.data`
section. Fortunately NASM already handles the escape characters.
- Fix some bugs with code generation, specifically using `movsx` to sign
extend the smaller types into 64-bit registers.
|
| |
|
|
|
|
| |
This made sense when all variables were of the same size, but now
with arrays we don't initialize them by default. Perhaps we should
find a way to 0-initialize all the memory?
|
| | |
|
| |
|
|
|
|
| |
Usual disclaimer at this point: Quick&Dirty implementation, hasn't
been tested other than basic sanity checks. Arrays are automatically
decayed into pointers when the identifier is accessed.
|
| |
|
|
|
|
| |
It was getting a bit unwieldy in `parser.c`, and this will potentially
help when we start dealing with more complex type-stuff such as
casting / conversions / etc.
|
| |
|
|
| |
With the fancy new type checking these are now required.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a bit of a chonky commit, but it adds in the basics of checking
the types of expressions / function calls / return types. There's still
a lot of work to be done, including:
(1) Adding new core types, and casting between allowed types
automatically
(2) Picking the corrent output type based on input types (for instance
float+int == float)
(3) We need much better error reporting, the error messages are really
vague and unhelpful as-is
(4) We also need to work to ensure that a function with a return type
actually returns
(5) Possible re-factoring to make stuff less hacky when we have more
types / structs / arrays / etc.
|
| |
|
|
|
|
| |
While I prefer the latter, the lexer/parser cannot correctly parse
`type&&` since it thinks `&&` is `TOKEN_AND`. Perhaps how these cases
are handled can be changed in the future.
|