Compare commits
No commits in common. "7d7626809d5f3686ab9de2dc0f52b9f22c48ec2d" and "c5781114a5cf427744bdd415603428a5c0c8aaa2" have entirely different histories.
7d7626809d
...
c5781114a5
275
Cargo.lock
generated
275
Cargo.lock
generated
@ -51,6 +51,39 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arraydeque"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ast-generator"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"yaml-rust2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.60"
|
version = "4.5.60"
|
||||||
@ -91,6 +124,17 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "codespan-reporting"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"termcolor",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codespan-reporting"
|
name = "codespan-reporting"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
@ -108,12 +152,75 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "convert_case"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
|
||||||
|
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 = "cst-test-generator"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deimos"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ast-generator",
|
||||||
|
"clap",
|
||||||
|
"codespan-reporting 0.12.0",
|
||||||
|
"cst-test-generator",
|
||||||
|
"indoc",
|
||||||
|
"log",
|
||||||
|
"pest",
|
||||||
|
"pest_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "dm"
|
name = "dm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"codespan-reporting",
|
"codespan-reporting 0.13.1",
|
||||||
"dm-std-lib",
|
"dm-std-lib",
|
||||||
"dmc-lib",
|
"dmc-lib",
|
||||||
"dvm-lib",
|
"dvm-lib",
|
||||||
@ -145,18 +252,138 @@ dependencies = [
|
|||||||
"dvm-lib",
|
"dvm-lib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding_rs"
|
||||||
|
version = "0.8.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
|
[[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 = "hashbrown"
|
||||||
|
version = "0.15.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indoc"
|
||||||
|
version = "2.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.167"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest"
|
||||||
|
version = "2.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"ucd-trie",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_derive"
|
||||||
|
version = "2.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_generator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_generator"
|
||||||
|
version = "2.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_meta",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_meta"
|
||||||
|
version = "2.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"sha2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.101"
|
version = "1.0.101"
|
||||||
@ -195,6 +422,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@ -221,12 +459,30 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -239,6 +495,12 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@ -320,3 +582,14 @@ name = "windows_x86_64_msvc"
|
|||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust2"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7"
|
||||||
|
dependencies = [
|
||||||
|
"arraydeque",
|
||||||
|
"encoding_rs",
|
||||||
|
"hashlink",
|
||||||
|
]
|
||||||
|
|||||||
27
Cargo.toml
27
Cargo.toml
@ -1,3 +1,28 @@
|
|||||||
|
[package]
|
||||||
|
name = "deimos"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
#[[bin]]
|
||||||
|
#name = "dm"
|
||||||
|
#path = "src/bin/dvm/lib"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "dmc"
|
||||||
|
path = "src/bin/dmc/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pest = { version = "2.8.4" }
|
||||||
|
clap = { version = "4.5.23", features = ["derive"] }
|
||||||
|
pest_derive = { version = "2.8.4", features = ["grammar-extras"] }
|
||||||
|
codespan-reporting = "0.12.0"
|
||||||
|
log = "0.4.27"
|
||||||
|
indoc = "2.0.6"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
ast-generator = { path = "ast-generator" }
|
||||||
|
cst-test-generator = { path = "cst-test-generator" }
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["dm", "dm-std-lib", "dmc-lib", "dvm-lib", "e2e-tests"]
|
members = ["ast-generator", "cst-test-generator", "dm", "dm-std-lib", "dmc-lib", "dvm-lib", "e2e-tests"]
|
||||||
|
|||||||
1
dm-book/.gitignore
vendored
1
dm-book/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
book
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
[book]
|
|
||||||
title = "Deimos Lang"
|
|
||||||
authors = ["Jesse Brault"]
|
|
||||||
language = "en"
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
# Introduction
|
|
||||||
|
|
||||||
Greetings! This is the manual for **Deimos Lang**, a programming language created by Jesse Brault. Deimos has the
|
|
||||||
planned following features:
|
|
||||||
|
|
||||||
- Basic object-oriented features and semantics, including interfaces, classes, and records.
|
|
||||||
- Enumerated (union) types like Rust/OCaml.
|
|
||||||
- Traits, which function similar to Rust traits or Haskell type-classes.
|
|
||||||
- Closures, including those with delegates like Groovy or Kotlin.
|
|
||||||
- Compile-time metaprogramming with template-like constructs.
|
|
||||||
- The usual imperative constructs: if/else, for/while loops, etc.
|
|
||||||
- Functional features, borrowed from languages such as OCaml, Rust, Haskell:
|
|
||||||
pattern matching, persistent data structures, and tail recursion.
|
|
||||||
- Static name-resolution and type-checking, with compiler type-inference as much as possible.
|
|
||||||
- Optional fully-dynamic dispatch via `dyn` keyword, providing runtime method/property lookup like Groovy or Ruby.
|
|
||||||
- A fast foreign-function interface FFI for calling native Rust functions.
|
|
||||||
|
|
||||||
Deimos is compiled for the **Deimos Virtual Machine** (DVM), a VM like those of Java and Lua in spirit but with a Rust
|
|
||||||
implementation and access to the rest of the Rust (and C, via Rust) ecosystem. The ultimate goal is to be able to run
|
|
||||||
Deimos and Lua side-by-side on the DVM, allowing applications both a statically typed language like Deimos to function
|
|
||||||
alongside and interface with a much more relaxed language like Lua.
|
|
||||||
|
|
||||||
## Hello, World!
|
|
||||||
|
|
||||||
Since it's standard practice to offer the classic Hello World program, let's get started!
|
|
||||||
|
|
||||||
```deimos
|
|
||||||
fn main()
|
|
||||||
println("Hello, World!")
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
Sometimes we just need to dump a string to the terminal, so `println` is available by default in all scopes. Indeed, all
|
|
||||||
items in the `std::core` module are imported by default to each file/module. In this case, the fully-qualified name of
|
|
||||||
`println` is `std::core::println`, and is located in the `print.dm` file under `std/core`:
|
|
||||||
|
|
||||||
```deimos
|
|
||||||
pub extern fn println(message: Any) -> Void
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, `println` is declared as an `extern` function, meaning its implementation is provided by a native function at
|
|
||||||
runtime. We can also see that it takes one parameter of type `Any`—where `Any` is the catchall super-type of all types
|
|
||||||
in the language. `Void` takes its usual meaning.
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# Summary
|
|
||||||
|
|
||||||
[Introduction](README.md)
|
|
||||||
|
|
||||||
- [Getting Started](getting_started.md)
|
|
||||||
- [Implementing Array List](./impl_array_list.md)
|
|
||||||
@ -1,159 +0,0 @@
|
|||||||
# Chapter 1: Getting Started
|
|
||||||
|
|
||||||
Deimos can be run both interactively via a read-eval-print loop (REPL) or by compiling and running a given source file.
|
|
||||||
|
|
||||||
## REPL
|
|
||||||
|
|
||||||
The REPL allows interactive programming similar to classic functional languages as well as Ruby. To start the REPL, run:
|
|
||||||
|
|
||||||
```
|
|
||||||
dm repl
|
|
||||||
```
|
|
||||||
|
|
||||||
### Basics
|
|
||||||
|
|
||||||
All statements and expressions in the REPL are scoped under a synthetic function; in other words, variables persist
|
|
||||||
through each input:
|
|
||||||
|
|
||||||
```
|
|
||||||
> let x = 2
|
|
||||||
> x
|
|
||||||
2
|
|
||||||
> let y = 3
|
|
||||||
> x + y
|
|
||||||
5
|
|
||||||
```
|
|
||||||
|
|
||||||
In addition to statements and expressions, functions can be defined in scope:
|
|
||||||
|
|
||||||
```
|
|
||||||
> fn double(x: Int) x * 2 end
|
|
||||||
> double(4)
|
|
||||||
8
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that variables in the "top" scope are not available inside defined functions:
|
|
||||||
|
|
||||||
```
|
|
||||||
> let x = 7
|
|
||||||
> fn doubleX() x * 2 end
|
|
||||||
Error: Symbol x could not be found.
|
|
||||||
```
|
|
||||||
|
|
||||||
This requires the use of closures, which can "capture" variables in their containing scope:
|
|
||||||
|
|
||||||
```
|
|
||||||
> let x = 42
|
|
||||||
> let doubleX = { x * 2 }
|
|
||||||
> doubleX()
|
|
||||||
84
|
|
||||||
```
|
|
||||||
|
|
||||||
Note the difference in syntax between function declarations and closure declarations. As we will later see, closures are
|
|
||||||
powerful constructs.
|
|
||||||
|
|
||||||
### Introduction to Classes
|
|
||||||
|
|
||||||
Classes can also be defined in the REPL:
|
|
||||||
|
|
||||||
```
|
|
||||||
> class Dog \
|
|
||||||
pub name: String \
|
|
||||||
pub ctor(name: String) \
|
|
||||||
self.name = name \
|
|
||||||
end \
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
A few things are going on here. First, note the use the backslash to indicate that we are not done with our input
|
|
||||||
(normally, a newline without a preceding backslash will cause the interpreter to consume everything input so far). Next,
|
|
||||||
note our syntax for declaring a class, with hints of Rust and Ruby:
|
|
||||||
|
|
||||||
- `class` keyword: the usual meaning
|
|
||||||
- `pub` keyword: makes a property or method available outside the class (i.e., non-private)
|
|
||||||
- `: Type` annotations: indicates the type of a property, parameter, or variable.
|
|
||||||
- `ctor` keyword: marks a constructor. *Note: Classes can only have **one** constructor*.
|
|
||||||
- `self` keyword, followed by property name: like the usual construct in OOP languages.
|
|
||||||
|
|
||||||
Once we've defined our class, we can use it:
|
|
||||||
|
|
||||||
```
|
|
||||||
> let bear = Dog("Bear")
|
|
||||||
> let skye = Dog("Skye")
|
|
||||||
> bear.name
|
|
||||||
Bear
|
|
||||||
> skye.name
|
|
||||||
Skye
|
|
||||||
```
|
|
||||||
|
|
||||||
Note above how we construct instances of the class by "calling" the class, exactly like we do in Kotlin.
|
|
||||||
|
|
||||||
#### Class Declaration Short Form
|
|
||||||
|
|
||||||
The above class example is a bit verbose; Deimos offers the following equivalent, inspired by Kotlin:
|
|
||||||
|
|
||||||
```
|
|
||||||
class Dog(pub name: String) end
|
|
||||||
```
|
|
||||||
|
|
||||||
This is especially useful in the REPL, where we may just want to declare a data type for doing some data processing.
|
|
||||||
|
|
||||||
```
|
|
||||||
> class Point(pub x: Int, pub y: Int) end
|
|
||||||
> fn double(p: Point) Point(p.x * 2, p.y * 2) end
|
|
||||||
> let a = Point(3, 4)
|
|
||||||
> double(a)
|
|
||||||
Point(6, 8)
|
|
||||||
> let b = Point(5, 6)
|
|
||||||
> double(double(b))
|
|
||||||
Point(20, 24)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compiling and Running Files
|
|
||||||
|
|
||||||
To compile and run a file, do:
|
|
||||||
|
|
||||||
```
|
|
||||||
dm run <your file name here>.dm
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the `.dm` extension is required in the command name (unlike `java`).
|
|
||||||
|
|
||||||
The above command will compile and immediately run the file. In order for a Deimos file to be executable, it must
|
|
||||||
contain a `main` function like the following:
|
|
||||||
|
|
||||||
```
|
|
||||||
fn main()
|
|
||||||
println("Hello, Deimos!")
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
Unlike the REPL, statements and expressions are not allowed in the top-level scope; they must be contained in a function
|
|
||||||
or method:
|
|
||||||
|
|
||||||
```
|
|
||||||
let x = 10 // ERROR! Will not parse.
|
|
||||||
```
|
|
||||||
|
|
||||||
However, functions, classes, and other top-level constructs are allowed:
|
|
||||||
|
|
||||||
```
|
|
||||||
fn double(p: Point) -> Point
|
|
||||||
Point(p.x * 2, p.y * 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
class Point(x: Int, y: Int) end
|
|
||||||
|
|
||||||
fn main()
|
|
||||||
let a = Point(1, 2)
|
|
||||||
let b = Point(3, 4)
|
|
||||||
println(double(a)) // Point(2, 4)
|
|
||||||
println(double(b)) // Point(6, 8)
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
let f = { a, b -> a + b } << 4
|
|
||||||
let x = f(5)
|
|
||||||
println(x) // 9
|
|
||||||
```
|
|
||||||
@ -1,296 +0,0 @@
|
|||||||
# Implementing Array List
|
|
||||||
|
|
||||||
```
|
|
||||||
trait Map<T>
|
|
||||||
fn <U> map(f: fn (T) -> U) -> Self<U>
|
|
||||||
end
|
|
||||||
|
|
||||||
trait Index<I>
|
|
||||||
type Output
|
|
||||||
|
|
||||||
op fn [] (index: I) -> Self::Output
|
|
||||||
end
|
|
||||||
|
|
||||||
trait Cons<T>
|
|
||||||
fn cons(t: T) -> Self<T>
|
|
||||||
fn head() -> Option<T>
|
|
||||||
fn tail() -> Self<T>
|
|
||||||
end
|
|
||||||
|
|
||||||
trait Default
|
|
||||||
static fn default() -> Self
|
|
||||||
end
|
|
||||||
|
|
||||||
int Iterable<T>
|
|
||||||
fn iter() -> Iterator<T>
|
|
||||||
|
|
||||||
def fn each(f: fn (T) -> Void)
|
|
||||||
for t in self
|
|
||||||
f(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
int Iterator<T>
|
|
||||||
fn next() -> Option<T>
|
|
||||||
end
|
|
||||||
|
|
||||||
#[intrinsic]
|
|
||||||
class Array<T> : Iterable<T>
|
|
||||||
pub extern static fn <T: Default> sized(size: Size) -> Array<T>
|
|
||||||
|
|
||||||
#[intrinsic]
|
|
||||||
pub fn len() -> Size end
|
|
||||||
|
|
||||||
#[intrinsic]
|
|
||||||
pub fn getAt(index: Size) -> T end
|
|
||||||
|
|
||||||
pub fn iter()
|
|
||||||
let mut i = 0
|
|
||||||
let iterator = {
|
|
||||||
if i < len() then
|
|
||||||
let next = Some(getAt(i))
|
|
||||||
i++
|
|
||||||
next
|
|
||||||
else
|
|
||||||
None
|
|
||||||
end
|
|
||||||
}
|
|
||||||
iterator
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
record Range<T>(start: T, end: T) end
|
|
||||||
|
|
||||||
impl<T> Index<Size> for Array<T>
|
|
||||||
type Output = T
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
op fn [] (index) = getAt(index)
|
|
||||||
end
|
|
||||||
|
|
||||||
impl<T> Index<Range<Size>> for Array<T>
|
|
||||||
type Output = Self<T>
|
|
||||||
|
|
||||||
op fn [] (range)
|
|
||||||
let ts = Self(range.end() - range.start())
|
|
||||||
for i in range do
|
|
||||||
ts[i] = self[i]
|
|
||||||
end
|
|
||||||
ts
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
impl<T: Default> Cons<T> for Array<T>
|
|
||||||
fn cons(t)
|
|
||||||
let ts = Array::<T>(len() + 1)
|
|
||||||
ts[0] = t
|
|
||||||
for i in 0..len() do
|
|
||||||
ts[i + 1] = self[i]
|
|
||||||
end
|
|
||||||
ts
|
|
||||||
end
|
|
||||||
|
|
||||||
fn head(t)
|
|
||||||
if len() > 0 then
|
|
||||||
self[0]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
fn tail()
|
|
||||||
if len() > 0 then
|
|
||||||
self[1..]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
int List<T> : Iterable<T>
|
|
||||||
fn len() -> Size
|
|
||||||
fn getAt(index: Size) -> Option<T>
|
|
||||||
fn slice(range: Range<Size>) -> Self<T>
|
|
||||||
|
|
||||||
mut fn add(t: T) -> Void
|
|
||||||
mut fn addAll(ts: Iterable<T>) -> Void
|
|
||||||
|
|
||||||
def mut op fn << (t: T) -> Void = add(t)
|
|
||||||
def mut op fn << (ts: Iterable<T>) -> Void = addAll(ts)
|
|
||||||
|
|
||||||
mut fn insert(t: T, index: Size) -> Void
|
|
||||||
|
|
||||||
def fn iter()
|
|
||||||
let mut i = 0
|
|
||||||
let iterator = {
|
|
||||||
if i < len() then
|
|
||||||
let next = getAt(i)
|
|
||||||
i++
|
|
||||||
next
|
|
||||||
else
|
|
||||||
None
|
|
||||||
end
|
|
||||||
}
|
|
||||||
iterator
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
impl<T> Map<T> for List<T>
|
|
||||||
fn map(f) = match self
|
|
||||||
[] => [],
|
|
||||||
head :: tail => f(head) :: tail.map(f)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
impl<T> Cons<T> for List<T>
|
|
||||||
fn cons(t)
|
|
||||||
let l = ArrayList(self.len() + 1)
|
|
||||||
l << t
|
|
||||||
l += self
|
|
||||||
l
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
impl<T> Index<Size> for List<T>
|
|
||||||
type Output = Option<T>
|
|
||||||
|
|
||||||
op fn [] (index) = getAt(index)
|
|
||||||
end
|
|
||||||
|
|
||||||
impl<T> Index<Range<Size>> for List<T>
|
|
||||||
type Output = Self<T>
|
|
||||||
|
|
||||||
op fn [] (range) = slice(range)
|
|
||||||
end
|
|
||||||
|
|
||||||
int UnsafeIterable<T>
|
|
||||||
fn iter() -> UnsafeIterator<T>
|
|
||||||
end
|
|
||||||
|
|
||||||
int UnsafeIterator<T>
|
|
||||||
unsafe fn next() -> Option<T> throws NullPointerException
|
|
||||||
|
|
||||||
def fn tryNext() -> Result<Option<T>, NullPointerException>
|
|
||||||
try
|
|
||||||
Ok(next())
|
|
||||||
catch e: NullPointerException
|
|
||||||
Err(e)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#[intrinsic]
|
|
||||||
class MaybeUninitArray<T> : UnsafeIterable<T>
|
|
||||||
pub extern static fn <T> sized(size: Size) -> Self<T>
|
|
||||||
|
|
||||||
#[intrinsic]
|
|
||||||
pub fn len() -> Size end
|
|
||||||
|
|
||||||
#[intrinsic]
|
|
||||||
pub unsafe fn getAt(index: Size) -> T throws NullPointerException end
|
|
||||||
|
|
||||||
class MaybeUninitIterator<T>(parent: MaybeUninitArray<T>) : UnsafeIterator<T>
|
|
||||||
mut i: Size = 0
|
|
||||||
|
|
||||||
pub unsafe fn next() -> Option<T> throws NullPointerException
|
|
||||||
if i < parent.len()
|
|
||||||
let next = parent.getAt(i)
|
|
||||||
i++
|
|
||||||
next
|
|
||||||
else
|
|
||||||
None
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
pub unsafe fn iter()
|
|
||||||
MaybeUninitIterator(self)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ArrayList<T> : List<T>
|
|
||||||
#[get]
|
|
||||||
mut len: Size = 0
|
|
||||||
|
|
||||||
mut ts = {% if T has Default then %}
|
|
||||||
Array<T>
|
|
||||||
{% else %}
|
|
||||||
MaybeUninitArray<T>
|
|
||||||
{% end %}
|
|
||||||
|
|
||||||
pub ctor(capacity: Size)
|
|
||||||
ts = {% if T has Default then %}
|
|
||||||
Array::sized::<T>(capacity)
|
|
||||||
%{ else %}
|
|
||||||
MaybeUninitArray::sized::<T>(capacity)
|
|
||||||
{% end %}
|
|
||||||
end
|
|
||||||
|
|
||||||
pub fn getAt(index)
|
|
||||||
{% if T has Default then %}
|
|
||||||
index < len ? Some(ts[index]) : None
|
|
||||||
{% else %}
|
|
||||||
if index < len then
|
|
||||||
try
|
|
||||||
Some(ts[index])
|
|
||||||
catch e: NullPointerException
|
|
||||||
None
|
|
||||||
end
|
|
||||||
else
|
|
||||||
None
|
|
||||||
end
|
|
||||||
{% end %}
|
|
||||||
end
|
|
||||||
|
|
||||||
pub fn slice(range)
|
|
||||||
/* some implementation */
|
|
||||||
end
|
|
||||||
|
|
||||||
mut fn maybeGrow()
|
|
||||||
if len + 1 == ts.len() then
|
|
||||||
let newSize = len * 2 // or whatever factor
|
|
||||||
|
|
||||||
let newTs = {% if T has Default then %}
|
|
||||||
Array::sized::<T>(newSize)
|
|
||||||
{% else %}
|
|
||||||
MaybeUninitArray::sized::<T>(newSize)
|
|
||||||
{% end %}
|
|
||||||
|
|
||||||
for i in 0..ts.len() do
|
|
||||||
newTs[i] = ts[i]
|
|
||||||
end
|
|
||||||
ts = newTs
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
pub mut fn add(t)
|
|
||||||
maybeGrow()
|
|
||||||
ts[len] = t
|
|
||||||
len++
|
|
||||||
end
|
|
||||||
|
|
||||||
pub mut fn addAll(ts)
|
|
||||||
ts.each { add(it) }
|
|
||||||
end
|
|
||||||
|
|
||||||
pub mut fn insert(t, i)
|
|
||||||
maybeGrow()
|
|
||||||
let mut previous = None
|
|
||||||
for i in i..len() do
|
|
||||||
match previous with
|
|
||||||
Some(p) => do
|
|
||||||
let cur = ts[i]
|
|
||||||
ts[i] = p
|
|
||||||
previous = Some(cur)
|
|
||||||
end
|
|
||||||
None => do
|
|
||||||
previous = Some(ts[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ts[i] = t
|
|
||||||
len++
|
|
||||||
end
|
|
||||||
end
|
|
||||||
```
|
|
||||||
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user