starting project Albireo
This commit is contained in:
commit
546af734e7
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
212
Cargo.lock
generated
Normal file
212
Cargo.lock
generated
Normal file
@ -0,0 +1,212 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "albireo"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "albireo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
pest = "2.7.6"
|
||||
pest_derive = "2.7.6"
|
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Albireo Programming Language
|
||||
|
||||
## Purpose of this project
|
||||
|
||||
For the sake of learning programming language theory, I decide to practice by applying what I knew and implementing them as I learn theories.
|
||||
|
||||
The language should be strictly typed and everything is pure. In that context, I design a language where everything is an expression. Side-effects will be handled either by Monads (or Applicative programming) or by using Effect Handlers (so called Algebraic Effects).
|
||||
|
||||
Complex types should be implemented, choices are Sub-typing, Row-Polymorphism, Algebraic Datatypes. Higher-Order Types (so called Kind) will also be implemented.
|
||||
|
||||
Advanced theory on Graded Types, Substructural Types (Linear or Affine) will be considered for implementation.
|
||||
|
||||
Everything is experimental and the current state of the language should reflect my personal experience as well as knowledge on programming language theory, including type theory and semantics. I do not intend to work extensively on compiler technology, although I am originated from learning assembly and binary analysis of programs.
|
117
src/albireo.pest
Normal file
117
src/albireo.pest
Normal file
@ -0,0 +1,117 @@
|
||||
keywords = {
|
||||
"number"
|
||||
| "bool"
|
||||
| "string"
|
||||
| "fn"
|
||||
| "true"
|
||||
| "false"
|
||||
| "is"
|
||||
| "in"
|
||||
| "if"
|
||||
| "then"
|
||||
| "else"
|
||||
| "let"
|
||||
| "only"
|
||||
| "as"
|
||||
| "function"
|
||||
| "import"
|
||||
| "module"
|
||||
| "export"
|
||||
}
|
||||
identifier = @{ !keywords ~ ASCII_ALPHA ~ ASCII_ALPHANUMERIC* }
|
||||
|
||||
function_type_param = { type }
|
||||
function_type_return = { type }
|
||||
function_type = {
|
||||
"fn" ~ function_type_param* ~ "=>" ~ function_type_return
|
||||
}
|
||||
|
||||
type = {
|
||||
function_type
|
||||
| "number"
|
||||
| "bool"
|
||||
| "string"
|
||||
}
|
||||
|
||||
number = @{ ASCII_DIGIT+ }
|
||||
string = @{ "\"" ~ !("\"") ~ ASCII_ALPHANUMERIC* ~ "\"" }
|
||||
bool = @{ "true" | "false" }
|
||||
function = { "function" ~ function_param* ~ "is" ~ function_body }
|
||||
function_param = { identifier }
|
||||
function_body = {
|
||||
binding* ~ expr
|
||||
}
|
||||
binding = {
|
||||
"let" ~ identifier ~ "=" ~ expr ~ "in"
|
||||
}
|
||||
|
||||
// will be expr in later version of the language
|
||||
if_cond = { identifier }
|
||||
if_branch = { identifier }
|
||||
else_branch = { identifier }
|
||||
if_expr = {
|
||||
// "if" ~ expr ~ "then" ~ expr ~ "else" ~ expr
|
||||
"if" ~ if_cond ~ "then" ~ if_branch ~ "else" ~ else_branch
|
||||
}
|
||||
|
||||
call_function = { identifier }
|
||||
call_param = { identifier | identifier ~ call_param }
|
||||
call_expr = {
|
||||
call_function ~ "(" ~ call_param? ~ ")"
|
||||
}
|
||||
|
||||
expr = {
|
||||
if_expr
|
||||
| call_expr
|
||||
| identifier
|
||||
| value
|
||||
}
|
||||
|
||||
// function is a value only if we allow to have thunks
|
||||
// or that function is a first-class citizen, FG-CBV
|
||||
// but it would a thunk if CBPV
|
||||
value = _{
|
||||
number
|
||||
| string
|
||||
| bool
|
||||
| function
|
||||
}
|
||||
|
||||
declaration = {
|
||||
identifier ~ ":" ~ type ~ "=" ~ expr
|
||||
}
|
||||
|
||||
module_name = @{ identifier }
|
||||
export_list = _{
|
||||
identifier
|
||||
| identifier ~ "," ~ export_list
|
||||
}
|
||||
module_export = {
|
||||
"export" ~ export_list
|
||||
}
|
||||
|
||||
// import module
|
||||
// import module only name, name
|
||||
// import module as change_name
|
||||
import_list = _{
|
||||
identifier ~ "," ~ import_list
|
||||
| identifier
|
||||
}
|
||||
import_selective = { "only" ~ import_list }
|
||||
import_change_name = { "as" ~ module_name }
|
||||
import_types = {
|
||||
import_selective
|
||||
| import_change_name
|
||||
}
|
||||
module_import = { "import" ~ module_name ~ import_types? }
|
||||
|
||||
module_declare = {
|
||||
"module" ~ module_name ~ module_export* ~ module_import*
|
||||
}
|
||||
|
||||
program = {
|
||||
module_declare ~ declaration*
|
||||
}
|
||||
|
||||
WHITESPACE = _{ " " | NEWLINE }
|
||||
COMMENT = _{ ";.*" ~ NEWLINE }
|
33
src/albireo.rs
Normal file
33
src/albireo.rs
Normal file
@ -0,0 +1,33 @@
|
||||
#[derive(pest_derive::Parser)]
|
||||
#[grammar = "albireo.pest"]
|
||||
pub struct AlbireoParser;
|
||||
|
||||
use pest::iterators::Pair;
|
||||
|
||||
struct Module {
|
||||
name: String,
|
||||
declaration: HashMap<String, Declaration>
|
||||
}
|
||||
|
||||
struct Declaration {
|
||||
type: Type,
|
||||
definition: Expression,
|
||||
}
|
||||
|
||||
enum Type {
|
||||
Number,
|
||||
String,
|
||||
Bool,
|
||||
Function(/*inputs*/Vec<Type>, /*output*/Type)
|
||||
}
|
||||
|
||||
// limitation as of now, everything must be passed in as identifier
|
||||
enum Expression {
|
||||
IfClause(String, String, String),
|
||||
Application(/*function name*/String, /*params*/Vec<String>), // function call
|
||||
Identifier(String),
|
||||
Number(u64),
|
||||
String(String),
|
||||
Bool(bool),
|
||||
Function(String, Vec<Binding>, Expression),
|
||||
}
|
17
src/main.rs
Normal file
17
src/main.rs
Normal file
@ -0,0 +1,17 @@
|
||||
mod albireo;
|
||||
|
||||
use crate::albireo::{AlbireoParser, Rule};
|
||||
|
||||
use std::fs;
|
||||
use pest::Parser;
|
||||
|
||||
fn main() {
|
||||
let input = fs::read_to_string("test/simple/main.air").expect("cannot read file");
|
||||
|
||||
let program = AlbireoParser::parse(Rule::program, &input)
|
||||
.expect("file format is wrong or the parser is wrong")
|
||||
.next()
|
||||
.expect("cannot parse input file as a Albireo program");
|
||||
|
||||
println!("{:?}", program);
|
||||
}
|
9
test/simple/main.air
Normal file
9
test/simple/main.air
Normal file
@ -0,0 +1,9 @@
|
||||
module main
|
||||
|
||||
c : fn => bool = function is
|
||||
let a = b in
|
||||
c(a)
|
||||
|
||||
b : bool = false
|
||||
|
||||
a : number = 1
|
Loading…
Reference in New Issue
Block a user