adam-mcdaniel / oakc

A portable programming language with a compact intermediate representation
Apache License 2.0
724 stars 21 forks source link

Added more predefined constants and `is_standard` method to Target trait #22

Closed adam-mcdaniel closed 4 years ago

adam-mcdaniel commented 4 years ago
This pull request implements the following constants: Constant name Value
TARGET The single character name of the target being compiled to.
IS_STANDARD Does the target output implement the standard Oak VM implementation?
ON_WINDOWS Was this program compiled on windows?
ON_MACOS Was this program compiled on macos?
ON_LINUX Was this program compiled on linux?
ON_NIX Was this program compiled on a unix system?
ON_NON_NIX Was this program compiled on a non-unix system?
DATE_DAY The day this program was compiled.
DATE_MONTH The month this program was compiled.
DATE_YEAR The year this program was compiled.
current_line() The line number where this operator is evoked
current_file() The name of the file where this operator is evoked
adam-mcdaniel commented 4 years ago

I'm not sure how I feel about implementing these constants in particular. I think more deliberation about which constants should be predefined is needed.

kevinramharak commented 4 years ago

I would agree to be careful in defining constants. What should the requirements be before adding a constant? Maybe wait until programs are written where certain constants are required?

adam-mcdaniel commented 4 years ago

I think implementing all of C's predefined constants would be a good first step. Oak's include / conditional compiling architecture mirrors a lot of C's preprocessor directives, so it only makes sense that having C's predefined constants would be useful. I also think any possible information about the target is also necessary to add, like whether or not the Target supports floats, etc.

What do you think?

kevinramharak commented 4 years ago

Id say taking some direction from C is a great start. But id be wary of implementing them all as it can get bloated quite fast.

I was also about to suggest that the Target gets some control about defining constants. Either by asking it questions like if it supports floats or giving it a hook to define constants. Maybe even both, im not sure how a language like C uses it. As some of those are language like features (TARGET) but others might be very specific for the target language itself.

dospunk commented 4 years ago

I think limiting the TARGET constant to one character is a bad idea, as it'll limit the number of backends and force the use of nondescriptive characters for potential backends that share a letter (ex. Java and JavaScript)

adam-mcdaniel commented 4 years ago

The latest commit added the current_line() and current_file() operators. current_line() can be used as a constant value anywhere, but current_file() can only be used anywhere a literal string expression can.

These operators will make it easier for runtime error reporting.

user panic: error on line 23, in file "fileio.ok"
adam-mcdaniel commented 4 years ago

The newest commit also adds the import compiler directive. This allows the compiler to include other files without redefinitions.

// main.ok
#[import("test1.ok")]
#[import("test2.ok")]

fn main() {
    test1();
    test2();
}
// test1.ok
fn test1() {
    putstrln("Test 1");
}
// test2.ok
#[import("test1.ok")]
fn test2() {
    test1(); // can use fns from test1
    putstrln("Test 2");
}

The import flag isn't actually represented in TIR at all. It's exclusively dealt with in the parser.

#[import("test.ok")]
// Expands to the declaration
#[if(!is_defined("test.ok") {
    #[define("test.ok", 1)]
    #[include("test.ok")]
}]
adam-mcdaniel commented 4 years ago

This commit adds typed constants. Before, all constants were of type num. Now, constants can be of type bool, char, or num depending on the constant expression. With this change, constants do not need to be typecasted to be used as conditions, for example.

fn platform() -> &char {
    return ON_WINDOWS? "windows"
                : ON_MACOS? "macOS"
                    : ON_LINUX? "linux"
                        : "unknown";
}