diff --git a/Cargo.lock b/Cargo.lock index 2b4b607..756990b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,6 +191,7 @@ dependencies = [ "either", "inkwell_internals", "libc", + "llvm-sys", "once_cell", "thiserror", ] @@ -218,6 +219,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.161" @@ -236,6 +243,19 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "llvm-sys" +version = "130.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20142c91fc4bde4036edbaf0d112f79667831d612efbaabe862ab9748fdd67c" +dependencies = [ + "cc", + "lazy_static", + "libc", + "regex", + "semver", +] + [[package]] name = "memchr" version = "2.7.2" @@ -341,6 +361,17 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" +[[package]] +name = "pest" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + [[package]] name = "pkg-config" version = "0.3.31" @@ -466,6 +497,24 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.210" @@ -647,6 +696,12 @@ dependencies = [ "time-core", ] +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "unicode-ident" version = "1.0.13" diff --git a/Cargo.toml b/Cargo.toml index cefdfd0..98d4280 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Somfic"] description = "The 'som' programming language" [dependencies] -inkwell = "0.5.0" +inkwell = { version = "0.5.0", features = ["llvm13-0"] } miette = { version = "7.2.0", features = ["fancy", "syntect-highlighter"] } owo-colors = "4.1.0" pretty_assertions = "1.4.1" diff --git a/readme.md b/readme.md index e63be55..345ce50 100644 --- a/readme.md +++ b/readme.md @@ -49,3 +49,17 @@ code Purrer for Cat: }; ``` + + +``` +install cmake +install strawberryperl + +winget install Ninja-build.Ninja + + +cargo install llvmenv +llvmenv init +llvmenv entries +llvmenv build-entry 10.0.0 +``` diff --git a/src/passer/mod.rs b/src/passer/mod.rs index 94b2fdb..4c787fa 100644 --- a/src/passer/mod.rs +++ b/src/passer/mod.rs @@ -23,3 +23,110 @@ impl PasserResult { self } } + +pub fn walk<'de>( + symbol: &Symbol<'de>, + statement_fn: fn(&Statement<'de>) -> Result, + expression_fn: fn(&Expression<'de>) -> Result, +) -> Result { + match symbol { + Symbol::Statement(statement) => walk_statement(statement, statement_fn, expression_fn), + Symbol::Expression(expression) => walk_expression(expression, statement_fn, expression_fn), + } +} + +fn walk_statement<'de>( + statement: &Statement<'de>, + statement_fn: fn(&Statement<'de>) -> Result, + expression_fn: fn(&Expression<'de>) -> Result, +) -> Result { + let mut result = statement_fn(statement)?; + + match &statement.value { + StatementValue::Block(statements) => { + for statement in statements { + result = result.combine(walk_statement(statement, statement_fn, expression_fn)?); + } + } + StatementValue::Expression(expression) => { + result = result.combine(walk_expression(expression, statement_fn, expression_fn)?); + } + StatementValue::Assignment { name, value } => { + result = result.combine(walk_expression(value, statement_fn, expression_fn)?); + } + StatementValue::Struct { name, fields } => {} + StatementValue::Enum { name, variants } => {} + StatementValue::Function { header, body } => { + result = result.combine(walk_expression(body, statement_fn, expression_fn)?); + } + StatementValue::Trait { name, functions } => {} + StatementValue::Return(expression) => { + result = result.combine(walk_expression(expression, statement_fn, expression_fn)?); + } + StatementValue::Conditional { + condition, + truthy, + falsy, + } => { + result = result.combine(walk_expression(condition, statement_fn, expression_fn)?); + result = result.combine(walk_statement(truthy, statement_fn, expression_fn)?); + if let Some(falsy) = falsy { + result = result.combine(walk_statement(falsy, statement_fn, expression_fn)?); + } + } + } + + Ok(result) +} + +fn walk_expression<'de>( + expression: &Expression<'de>, + statement_fn: fn(&Statement<'de>) -> Result, + expression_fn: fn(&Expression<'de>) -> Result, +) -> Result { + let mut result = expression_fn(expression)?; + + match &expression.value { + ExpressionValue::Binary { + operator, + left, + right, + } => { + result = result.combine(walk_expression(left, statement_fn, expression_fn)?); + result = result.combine(walk_expression(right, statement_fn, expression_fn)?); + } + ExpressionValue::Unary { operator, operand } => { + result = result.combine(walk_expression(operand, statement_fn, expression_fn)?); + } + ExpressionValue::Group(expression) => { + result = result.combine(walk_expression(expression, statement_fn, expression_fn)?); + } + ExpressionValue::Block { + statements, + return_value, + } => { + for statement in statements { + result = result.combine(walk_statement(statement, statement_fn, expression_fn)?); + } + result = result.combine(walk_expression(return_value, statement_fn, expression_fn)?); + } + ExpressionValue::Conditional { + condition, + truthy, + falsy, + } => { + result = result.combine(walk_expression(condition, statement_fn, expression_fn)?); + result = result.combine(walk_expression(truthy, statement_fn, expression_fn)?); + result = result.combine(walk_expression(falsy, statement_fn, expression_fn)?); + } + ExpressionValue::Call { callee, arguments } => { + result = result.combine(walk_expression(callee, statement_fn, expression_fn)?); + for argument in arguments { + result = result.combine(walk_expression(argument, statement_fn, expression_fn)?); + } + } + ExpressionValue::Primitive(_) => {} + } + + Ok(result) +} diff --git a/src/passer/typing/mod.rs b/src/passer/typing/mod.rs index c0395fc..14e79a2 100644 --- a/src/passer/typing/mod.rs +++ b/src/passer/typing/mod.rs @@ -54,113 +54,6 @@ impl Passer for TypingPasser { } } -pub fn walk<'de>( - symbol: &Symbol<'de>, - statement_fn: fn(&Statement<'de>) -> Result, - expression_fn: fn(&Expression<'de>) -> Result, -) -> Result { - match symbol { - Symbol::Statement(statement) => walk_statement(statement, statement_fn, expression_fn), - Symbol::Expression(expression) => walk_expression(expression, statement_fn, expression_fn), - } -} - -pub fn walk_statement<'de>( - statement: &Statement<'de>, - statement_fn: fn(&Statement<'de>) -> Result, - expression_fn: fn(&Expression<'de>) -> Result, -) -> Result { - let mut result = statement_fn(statement)?; - - match &statement.value { - StatementValue::Block(statements) => { - for statement in statements { - result = result.combine(walk_statement(statement, statement_fn, expression_fn)?); - } - } - StatementValue::Expression(expression) => { - result = result.combine(walk_expression(expression, statement_fn, expression_fn)?); - } - StatementValue::Assignment { name, value } => { - result = result.combine(walk_expression(value, statement_fn, expression_fn)?); - } - StatementValue::Struct { name, fields } => {} - StatementValue::Enum { name, variants } => {} - StatementValue::Function { header, body } => { - result = result.combine(walk_expression(body, statement_fn, expression_fn)?); - } - StatementValue::Trait { name, functions } => {} - StatementValue::Return(expression) => { - result = result.combine(walk_expression(expression, statement_fn, expression_fn)?); - } - StatementValue::Conditional { - condition, - truthy, - falsy, - } => { - result = result.combine(walk_expression(condition, statement_fn, expression_fn)?); - result = result.combine(walk_statement(truthy, statement_fn, expression_fn)?); - if let Some(falsy) = falsy { - result = result.combine(walk_statement(falsy, statement_fn, expression_fn)?); - } - } - } - - Ok(result) -} - -pub fn walk_expression<'de>( - expression: &Expression<'de>, - statement_fn: fn(&Statement<'de>) -> Result, - expression_fn: fn(&Expression<'de>) -> Result, -) -> Result { - let mut result = expression_fn(expression)?; - - match &expression.value { - ExpressionValue::Binary { - operator, - left, - right, - } => { - result = result.combine(walk_expression(left, statement_fn, expression_fn)?); - result = result.combine(walk_expression(right, statement_fn, expression_fn)?); - } - ExpressionValue::Unary { operator, operand } => { - result = result.combine(walk_expression(operand, statement_fn, expression_fn)?); - } - ExpressionValue::Group(expression) => { - result = result.combine(walk_expression(expression, statement_fn, expression_fn)?); - } - ExpressionValue::Block { - statements, - return_value, - } => { - for statement in statements { - result = result.combine(walk_statement(statement, statement_fn, expression_fn)?); - } - result = result.combine(walk_expression(return_value, statement_fn, expression_fn)?); - } - ExpressionValue::Conditional { - condition, - truthy, - falsy, - } => { - result = result.combine(walk_expression(condition, statement_fn, expression_fn)?); - result = result.combine(walk_expression(truthy, statement_fn, expression_fn)?); - result = result.combine(walk_expression(falsy, statement_fn, expression_fn)?); - } - ExpressionValue::Call { callee, arguments } => { - result = result.combine(walk_expression(callee, statement_fn, expression_fn)?); - for argument in arguments { - result = result.combine(walk_expression(argument, statement_fn, expression_fn)?); - } - } - ExpressionValue::Primitive(_) => {} - } - - Ok(result) -} - pub trait Typing<'de> { fn possible_types(&self) -> Vec>; }