mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 07:58:24 +00:00
allow top level module
This commit is contained in:
parent
0ea6ac3085
commit
7c3bc054e5
20
README.md
20
README.md
|
@ -5,18 +5,16 @@ An experimental statically-typed compiled programming language made with LLVM an
|
||||||
Syntax is subject to change any time right now. It has a rusty style for now.
|
Syntax is subject to change any time right now. It has a rusty style for now.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
mod Main {
|
pub fn main() -> i32 {
|
||||||
pub fn main() -> i32 {
|
let b: i32 = factorial(4);
|
||||||
let b: i32 = factorial(4);
|
return b;
|
||||||
return b;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn factorial(n: i32) -> i32 {
|
pub fn factorial(n: i32) -> i32 {
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
return n;
|
return n;
|
||||||
} else {
|
} else {
|
||||||
return n * factorial(n - 1);
|
return n * factorial(n - 1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -114,30 +114,18 @@ fn main() -> Result<()> {
|
||||||
if bin {
|
if bin {
|
||||||
std::fs::write(
|
std::fs::write(
|
||||||
path.join("src").join("main.ed"),
|
path.join("src").join("main.ed"),
|
||||||
format!(
|
r#"pub fn main() -> i32 {{
|
||||||
r#"
|
return 0;
|
||||||
mod {} {{
|
}"#,
|
||||||
pub fn main() -> i32 {{
|
|
||||||
return 0;
|
|
||||||
}}
|
|
||||||
}}"#,
|
|
||||||
name
|
|
||||||
),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if lib {
|
if lib {
|
||||||
std::fs::write(
|
std::fs::write(
|
||||||
path.join("src").join("lib.ed"),
|
path.join("src").join("lib.ed"),
|
||||||
format!(
|
r#"pub fn main() -> i32 {{
|
||||||
r#"
|
return 0;
|
||||||
mod {} {{
|
}"#,
|
||||||
pub fn hello_world() -> i32 {{
|
|
||||||
return 0;
|
|
||||||
}}
|
|
||||||
}}"#,
|
|
||||||
name
|
|
||||||
),
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,13 @@ pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
|
||||||
for path in files {
|
for path in files {
|
||||||
let source = std::fs::read_to_string(&path)?;
|
let source = std::fs::read_to_string(&path)?;
|
||||||
|
|
||||||
let modules_ast = edlang_parser::parse_ast(&source);
|
let module_ast = edlang_parser::parse_ast(
|
||||||
|
&source,
|
||||||
|
&path.file_stem().expect("no file stem").to_string_lossy(),
|
||||||
|
);
|
||||||
|
|
||||||
let modules_temp = match modules_ast {
|
let module_temp = match module_ast {
|
||||||
Ok(modules) => modules,
|
Ok(module) => module,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let path = path.display().to_string();
|
let path = path.display().to_string();
|
||||||
let report = edlang_parser::error_to_report(&path, &error)?;
|
let report = edlang_parser::error_to_report(&path, &error)?;
|
||||||
|
@ -110,7 +113,7 @@ pub fn compile(args: &CompilerArgs) -> Result<PathBuf> {
|
||||||
std::process::exit(1)
|
std::process::exit(1)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
modules.push((path, source, modules_temp));
|
modules.push((path, source, module_temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
let session = Session {
|
let session = Session {
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub fn compile_program(
|
||||||
name: &str,
|
name: &str,
|
||||||
library: bool,
|
library: bool,
|
||||||
) -> Result<CompileResult, Box<dyn std::error::Error>> {
|
) -> Result<CompileResult, Box<dyn std::error::Error>> {
|
||||||
let modules = edlang_parser::parse_ast(source).unwrap();
|
let module = edlang_parser::parse_ast(source, name).unwrap();
|
||||||
|
|
||||||
let test_dir = tempfile::tempdir().unwrap();
|
let test_dir = tempfile::tempdir().unwrap();
|
||||||
let test_dir_path = test_dir.path().canonicalize()?;
|
let test_dir_path = test_dir.path().canonicalize()?;
|
||||||
|
@ -61,7 +61,7 @@ pub fn compile_program(
|
||||||
output_asm: false,
|
output_asm: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let program_ir = lower_modules(&[modules]).unwrap();
|
let program_ir = lower_modules(&[module]).unwrap();
|
||||||
|
|
||||||
let object_path = edlang_codegen_llvm::compile(&session, &program_ir).unwrap();
|
let object_path = edlang_codegen_llvm::compile(&session, &program_ir).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub struct ProgramBody {
|
||||||
pub structs: BTreeMap<DefId, AdtBody>,
|
pub structs: BTreeMap<DefId, AdtBody>,
|
||||||
/// The function signatures.
|
/// The function signatures.
|
||||||
pub function_signatures: BTreeMap<DefId, (Vec<TypeInfo>, TypeInfo)>,
|
pub function_signatures: BTreeMap<DefId, (Vec<TypeInfo>, TypeInfo)>,
|
||||||
|
pub file_names: BTreeMap<usize, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -15,33 +15,27 @@ mod common;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
mod prepass;
|
mod prepass;
|
||||||
|
|
||||||
pub fn lower_modules(modules: &[Vec<ast::Module>]) -> Result<ProgramBody, LoweringError> {
|
pub fn lower_modules(modules: &[ast::Module]) -> Result<ProgramBody, LoweringError> {
|
||||||
let mut ctx = BuildCtx::default();
|
let mut ctx = BuildCtx::default();
|
||||||
|
|
||||||
// resolve symbols
|
// resolve symbols
|
||||||
for (file_id, modules) in modules.iter().enumerate() {
|
for (file_id, module) in modules.iter().enumerate() {
|
||||||
for module in modules {
|
ctx = prepass::prepass_module(ctx, module, file_id)?;
|
||||||
ctx = prepass::prepass_module(ctx, module, file_id)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve imports
|
// resolve imports
|
||||||
for (file_id, modules) in modules.iter().enumerate() {
|
for (file_id, module) in modules.iter().enumerate() {
|
||||||
for module in modules {
|
ctx = prepass::prepass_imports(ctx, module, file_id)?;
|
||||||
ctx = prepass::prepass_imports(ctx, module, file_id)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for modules in modules {
|
for mod_def in modules {
|
||||||
for mod_def in modules {
|
let id = *ctx
|
||||||
let id = *ctx
|
.body
|
||||||
.body
|
.top_level_module_names
|
||||||
.top_level_module_names
|
.get(&mod_def.name.name)
|
||||||
.get(&mod_def.name.name)
|
.expect("module should exist");
|
||||||
.expect("module should exist");
|
|
||||||
|
|
||||||
ctx = lower_module(ctx, mod_def, id)?;
|
ctx = lower_module(ctx, mod_def, id)?;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ctx.body)
|
Ok(ctx.body)
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::lexer::LexicalError;
|
||||||
use edlang_ast as ast;
|
use edlang_ast as ast;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
grammar;
|
grammar<'module_name>(module_name: &'module_name str);
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
type Location = usize;
|
type Location = usize;
|
||||||
|
@ -478,8 +478,16 @@ pub(crate) Import: ast::Import = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub Modules: Vec<ast::Module> = {
|
pub TopLevelModule: ast::Module = {
|
||||||
<Module+> => <>
|
<lo:@L> <imports:List<Import>?> <contents:List<ModuleStatement>> <hi:@R> => ast::Module {
|
||||||
|
name: ast::Ident {
|
||||||
|
name: module_name.to_string(),
|
||||||
|
span: ast::Span::new(0, 0),
|
||||||
|
},
|
||||||
|
imports: imports.unwrap_or(vec![]),
|
||||||
|
contents,
|
||||||
|
span: ast::Span::new(lo, hi),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub Module: ast::Module = {
|
pub Module: ast::Module = {
|
||||||
|
|
|
@ -22,10 +22,11 @@ pub mod grammar {
|
||||||
|
|
||||||
pub fn parse_ast(
|
pub fn parse_ast(
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> Result<Vec<edlang_ast::Module>, ParseError<usize, Token, LexicalError>> {
|
module_name: &str,
|
||||||
|
) -> Result<edlang_ast::Module, ParseError<usize, Token, LexicalError>> {
|
||||||
let lexer = Lexer::new(source);
|
let lexer = Lexer::new(source);
|
||||||
let parser = grammar::ModulesParser::new();
|
let parser = grammar::TopLevelModuleParser::new();
|
||||||
parser.parse(lexer)
|
parser.parse(module_name, lexer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_report<'a>(
|
pub fn print_report<'a>(
|
||||||
|
|
Loading…
Reference in a new issue