mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Compare commits
5 commits
682178bec9
...
1079d53f05
Author | SHA1 | Date | |
---|---|---|---|
Natapat Samutpong | 1079d53f05 | ||
Natapat Samutpong | 9fb5a8e715 | ||
Natapat Samutpong | a56f08b9f8 | ||
Natapat Samutpong | 41a037077a | ||
Natapat Samutpong | 63701f743b |
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1 +1,10 @@
|
||||||
/target
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
debug/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# These are backup files generated by rustfmt
|
||||||
|
**/*.rs.bk
|
||||||
|
|
||||||
|
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||||
|
*.pdb
|
51
Cargo.lock
generated
51
Cargo.lock
generated
|
@ -60,9 +60,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.0.14"
|
version = "3.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b63edc3f163b3c71ec8aa23f9bd6070f77edbf3d1d198b164afa90ff00e4ec62"
|
checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -77,9 +77,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "3.0.14"
|
version = "3.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a1132dc3944b31c20dd8b906b3a9f0a5d0243e092d59171414969657ac6aa85"
|
checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
|
@ -154,14 +154,15 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
name = "hc"
|
name = "hc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ariadne",
|
|
||||||
"chumsky",
|
|
||||||
"clap",
|
"clap",
|
||||||
"codegen",
|
"codegen",
|
||||||
"diagnostic",
|
"diagnostic",
|
||||||
"hir",
|
"hir",
|
||||||
"lexer",
|
"lexer",
|
||||||
"parser",
|
"parser",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -211,9 +212,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.117"
|
version = "0.2.119"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
|
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
|
@ -286,6 +287,23 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.136"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.136"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -305,18 +323,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.2"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.14.2"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-keccak"
|
name = "tiny-keccak"
|
||||||
|
@ -327,6 +345,15 @@ dependencies = [
|
||||||
"crunchy",
|
"crunchy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
15
README.md
15
README.md
|
@ -4,14 +4,21 @@ Programming language that compiles to C++!
|
||||||
Note: Everything in this project can be changed at anytime! (I'm still finding out what work best for lots of thing) if you have an idea, feel free to create an issues about it, or even create a PR! (I'd be very happy)
|
Note: Everything in this project can be changed at anytime! (I'm still finding out what work best for lots of thing) if you have an idea, feel free to create an issues about it, or even create a PR! (I'd be very happy)
|
||||||
|
|
||||||
# Prerequistie
|
# Prerequistie
|
||||||
- `clang++`(preferred) or any C++ compiler
|
- `clang++`(preferred, default) or any C++ compiler
|
||||||
- Rust (if you're going to build from source)
|
- Rust (if you're going to build from source)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
You can also configurate Hades compiler (currently you can only change the C++ compiler). Make a new file called `hades.toml` in the current working directory and the compiler will look for it! if there isn't one then it will use the default configuration:
|
||||||
|
```toml
|
||||||
|
[compiler]
|
||||||
|
compiler = "clang++"
|
||||||
|
```
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
> This is only contains important TODOs, smaller TODOs isn't listed here and instead scattered around among sources code.
|
||||||
|
- More compiler configuration (e.x. complier options)
|
||||||
- Optimization (IR)
|
- Optimization (IR)
|
||||||
- Error reporting (probably with Ariadne crate)
|
- Standard library & Runtime stuff
|
||||||
- Standard library
|
|
||||||
- Runtime stuff
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
Hades is licensed under both [MIT license](https://github.com/azur1s/hades/blob/master/LICENSE-MIT) and [Apache License](https://github.com/azur1s/hades/blob/master/LICENSE-APACHE)
|
Hades is licensed under both [MIT license](https://github.com/azur1s/hades/blob/master/LICENSE-MIT) and [Apache License](https://github.com/azur1s/hades/blob/master/LICENSE-APACHE)
|
||||||
|
|
|
@ -111,9 +111,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
|
||||||
.or(keyword)
|
.or(keyword)
|
||||||
.recover_with(skip_then_retry_until([]));
|
.recover_with(skip_then_retry_until([]));
|
||||||
|
|
||||||
let comment = just("--")
|
let comment = just("--").then(take_until(just('\n'))).padded();
|
||||||
.ignore_then(filter(|c| *c != '\n').repeated())
|
|
||||||
.then_ignore(just('\n'));
|
|
||||||
|
|
||||||
token
|
token
|
||||||
.padded_by(comment.repeated())
|
.padded_by(comment.repeated())
|
||||||
|
|
|
@ -5,11 +5,21 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# Argument handling
|
||||||
clap = { version = "3.0.14", features = ["derive"] }
|
clap = { version = "3.0.14", features = ["derive"] }
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
toml = "0.5"
|
||||||
|
serde = "1.0.136"
|
||||||
|
serde_derive = "1.0.136"
|
||||||
|
|
||||||
|
# Parsing
|
||||||
lexer = { path = "../lexer" }
|
lexer = { path = "../lexer" }
|
||||||
parser = { path = "../parser" }
|
parser = { path = "../parser" }
|
||||||
|
|
||||||
|
# Diagnostics
|
||||||
diagnostic = { path = "../diagnostic" }
|
diagnostic = { path = "../diagnostic" }
|
||||||
|
|
||||||
|
# Codegen
|
||||||
hir = { path = "../hir" }
|
hir = { path = "../hir" }
|
||||||
codegen = { path = "../codegen" }
|
codegen = { path = "../codegen" }
|
||||||
chumsky = "0.8.0"
|
|
||||||
ariadne = "0.1.5"
|
|
25
crates/main/src/config.rs
Normal file
25
crates/main/src/config.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use toml::{from_str, de::Error};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub compiler: CompilerOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CompilerOptions {
|
||||||
|
pub compiler: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_config() -> Config {
|
||||||
|
Config {
|
||||||
|
compiler: CompilerOptions {
|
||||||
|
compiler: "clang++".to_string(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_config(toml_content: &str) -> Result<Config, Error> {
|
||||||
|
let config: Config = from_str(toml_content)?;
|
||||||
|
Ok(config)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{fs, io::Write};
|
use std::{fs, io::Write, process::Command};
|
||||||
|
|
||||||
use clap::Parser as ArgParser;
|
use clap::Parser as ArgParser;
|
||||||
|
|
||||||
|
@ -11,10 +11,31 @@ use codegen::cpp;
|
||||||
pub mod args;
|
pub mod args;
|
||||||
use args::{Args, Options};
|
use args::{Args, Options};
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
|
|
||||||
pub mod util;
|
pub mod util;
|
||||||
use crate::util::log;
|
use crate::util::log;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let config_file = fs::read_to_string("./hades.toml");
|
||||||
|
let config: config::Config;
|
||||||
|
match config_file {
|
||||||
|
Ok(content) => {
|
||||||
|
let parsed = config::parse_config(&content);
|
||||||
|
match parsed {
|
||||||
|
Ok(c) => config = c,
|
||||||
|
Err(e) => {
|
||||||
|
log(2, format!("{}", e));
|
||||||
|
config = config::default_config();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log(1, format!("Error reading config file: {}, using default config", e));
|
||||||
|
config = config::default_config();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
match args.options {
|
match args.options {
|
||||||
Options::Compile {
|
Options::Compile {
|
||||||
|
@ -43,6 +64,7 @@ fn main() {
|
||||||
for err in lex_error { diagnostics.add_lex_error(err); }
|
for err in lex_error { diagnostics.add_lex_error(err); }
|
||||||
for err in parse_error { diagnostics.add_parse_error(err); }
|
for err in parse_error { diagnostics.add_parse_error(err); }
|
||||||
|
|
||||||
|
// Report syntax errors if any
|
||||||
if diagnostics.has_error() {
|
if diagnostics.has_error() {
|
||||||
diagnostics.display(src);
|
diagnostics.display(src);
|
||||||
logif!(0, "Epic parsing fail");
|
logif!(0, "Epic parsing fail");
|
||||||
|
@ -56,6 +78,8 @@ fn main() {
|
||||||
// Convert the AST to HIR
|
// Convert the AST to HIR
|
||||||
let (ir, lowering_error) = ast_to_ir(ast);
|
let (ir, lowering_error) = ast_to_ir(ast);
|
||||||
for err in lowering_error { diagnostics.add_lowering_error(err); }
|
for err in lowering_error { diagnostics.add_lowering_error(err); }
|
||||||
|
|
||||||
|
// Report lowering errors if any
|
||||||
if diagnostics.has_error() {
|
if diagnostics.has_error() {
|
||||||
diagnostics.display(src);
|
diagnostics.display(src);
|
||||||
logif!(0, "Epic Lowering(HIR) fail");
|
logif!(0, "Epic Lowering(HIR) fail");
|
||||||
|
@ -77,15 +101,20 @@ fn main() {
|
||||||
let mut file = fs::File::create(&output_path).expect("Failed to create file");
|
let mut file = fs::File::create(&output_path).expect("Failed to create file");
|
||||||
file.write_all(codegen.emitted.as_bytes()).expect("Failed to write to file");
|
file.write_all(codegen.emitted.as_bytes()).expect("Failed to write to file");
|
||||||
|
|
||||||
|
// Compile the generate code
|
||||||
|
let compiler = &config.compiler.compiler;
|
||||||
|
Command::new(compiler)
|
||||||
|
.arg(&output_path)
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to run compiler");
|
||||||
|
|
||||||
// End timer
|
// End timer
|
||||||
let duration = start.elapsed().as_millis();
|
let duration = start.elapsed().as_millis();
|
||||||
|
|
||||||
logif!(0, format!("Compilation took {}ms", duration));
|
logif!(0, format!("Compilation took {}ms", duration));
|
||||||
logif!(0, format!("Wrote output to `{}`. All done.", output_path.display()));
|
logif!(0, format!("Wrote output to `{}`", output_path.display()));
|
||||||
},
|
},
|
||||||
None => {
|
None => { unreachable!(); }
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
hades.toml
Normal file
2
hades.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[compiler]
|
||||||
|
compiler = "clang++"
|
Loading…
Reference in a new issue