a new AST module
This commit is contained in:
parent
c8f3be4df8
commit
cb4733b61d
32 changed files with 230317 additions and 14991 deletions
|
@ -1,6 +1,7 @@
|
|||
ARG VARIANT "bookworm-20240612"
|
||||
ARG VARIANT "bookworm-20240701"
|
||||
|
||||
FROM debian:${VARIANT}
|
||||
# FROM debian:${VARIANT}
|
||||
FROM debian:bookworm-20240701
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
sudo \
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
"VARIANT": "bookworm-20240612", }
|
||||
"VARIANT": "bookworm-20240701"
|
||||
}
|
||||
},
|
||||
"runArgs": [
|
||||
"--device=/dev/kvm",
|
||||
|
|
12
.github/workflows/clippy.yml
vendored
12
.github/workflows/clippy.yml
vendored
|
@ -21,20 +21,14 @@ on:
|
|||
jobs:
|
||||
rust-clippy-analyze:
|
||||
name: Run rust-clippy analyzing
|
||||
runs-on: self-hosted
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
|
||||
|
||||
|
||||
steps:
|
||||
- name: Modify hosts file
|
||||
run: |
|
||||
echo "66.241.125.220 ok.software" >> /etc/hosts
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af #@v1
|
||||
with:
|
||||
|
@ -42,10 +36,8 @@ jobs:
|
|||
toolchain: stable
|
||||
components: clippy
|
||||
override: true
|
||||
|
||||
- name: Install required cargo
|
||||
run: cargo install clippy-sarif sarif-fmt
|
||||
|
||||
- name: Run rust-clippy
|
||||
run:
|
||||
cargo clippy
|
||||
|
@ -57,4 +49,4 @@ jobs:
|
|||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: rust-clippy-results.sarif
|
||||
wait-for-processing: true
|
||||
wait-for-processing: true
|
||||
|
|
13
.github/workflows/mdbook.yml
vendored
13
.github/workflows/mdbook.yml
vendored
|
@ -8,6 +8,8 @@ on:
|
|||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
@ -29,6 +31,14 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/sevki/devcontainer:main
|
||||
strategy:
|
||||
matrix:
|
||||
targets: [
|
||||
x86_64-unknown-linux-gnu
|
||||
]
|
||||
packages: [srclang]
|
||||
toolchains: [stable]
|
||||
|
||||
env:
|
||||
MDBOOK_VERSION: 0.4.40
|
||||
steps:
|
||||
|
@ -38,7 +48,7 @@ jobs:
|
|||
rustup toolchain install ${{ matrix.toolchains }}
|
||||
rustup component add cargo
|
||||
rustup component add clippy
|
||||
rustup component add rust-src
|
||||
rustup component add rust-src
|
||||
rustup target add ${{ matrix.targets }}
|
||||
rustup update
|
||||
- name: Install mdBook
|
||||
|
@ -65,6 +75,7 @@ jobs:
|
|||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
|
|
41
.github/workflows/rust-linux.yml
vendored
Normal file
41
.github/workflows/rust-linux.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
name: Rust
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
MDBOOK_VERSION: 0.4.40
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/sevki/devcontainer:main
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
targets:
|
||||
- x86_64-unknown-linux-gnu
|
||||
packages:
|
||||
- srclang
|
||||
toolchains:
|
||||
- stable
|
||||
- nightly
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: rustup update
|
||||
run: |
|
||||
rustup toolchain install ${{ matrix.toolchains }}
|
||||
rustup component add cargo
|
||||
rustup component add clippy
|
||||
rustup component add rust-src
|
||||
rustup target add ${{ matrix.targets }}
|
||||
rustup update
|
||||
- name: Build ${{ matrix.packages }} for ${{ matrix.targets }}
|
||||
run: cargo build --verbose --target ${{ matrix.targets }} -p ${{ matrix.packages }}
|
||||
- name: Test ${{ matrix.packages }} for ${{ matrix.targets }}
|
||||
run: cargo test --verbose --target ${{ matrix.targets }} -p ${{ matrix.packages }}
|
61
.github/workflows/rust.yml
vendored
61
.github/workflows/rust.yml
vendored
|
@ -1,61 +0,0 @@
|
|||
name: Rust
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
MDBOOK_VERSION: 0.4.40
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/sevki/devcontainer:main
|
||||
strategy:
|
||||
matrix:
|
||||
targets: [
|
||||
wasm32-unknown-unknown
|
||||
# , x86_64-unknown-linux-gnu
|
||||
]
|
||||
packages: [srclang
|
||||
# ,src-lsp-server, src-lsp-browser
|
||||
]
|
||||
toolchains: [stable
|
||||
# , nightly
|
||||
]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: rustup update
|
||||
run: |
|
||||
rustup toolchain install ${{ matrix.toolchains }}
|
||||
rustup component add cargo
|
||||
rustup component add clippy
|
||||
rustup component add rust-src
|
||||
rustup target add ${{ matrix.targets }}
|
||||
rustup update
|
||||
# - name: Build ${{ matrix.packages }} for ${{ matrix.targets }}
|
||||
# run: cargo build --verbose --target ${{ matrix.targets }} -p ${{ matrix.packages }}
|
||||
# - name: Test ${{ matrix.packages }} for ${{ matrix.targets }}
|
||||
# run: cargo test --verbose --target ${{ matrix.targets }} -p ${{ matrix.packages }}
|
||||
- name: Install mdBook
|
||||
run: |
|
||||
cargo install --version ${MDBOOK_VERSION} mdbook
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: install deps
|
||||
run: |
|
||||
cargo install mdbook-svgbob@0.2.0
|
||||
cargo install mdbook-alerts
|
||||
- name: Build with mdBook
|
||||
run: mdbook build
|
||||
- name: Build the ide
|
||||
run: |
|
||||
cd packages/app
|
||||
npm install
|
||||
npm run build
|
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -973,6 +973,12 @@ dependencies = [
|
|||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -1515,11 +1521,13 @@ dependencies = [
|
|||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
"okstd",
|
||||
"paste",
|
||||
"phf_codegen",
|
||||
"proptest",
|
||||
"ropey",
|
||||
"salsa-2022",
|
||||
"salsa-2022-macros",
|
||||
"src-derive",
|
||||
"syn 2.0.66",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
|
|
@ -5,7 +5,9 @@ edition = "2021"
|
|||
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/src-collections", "crates/src-derive", "crates/src-derive-test",
|
||||
"crates/src-collections",
|
||||
"crates/src-derive",
|
||||
"crates/src-derive-test",
|
||||
"crates/src-lsp-browser",
|
||||
"crates/src-lsp-server",
|
||||
]
|
||||
|
@ -32,6 +34,8 @@ syn = "2.0.60"
|
|||
bitflags = "2.5.0"
|
||||
ropey = { version = "1.6.1", features = ["small_chunks"] }
|
||||
hashbrown = "0.14.5"
|
||||
src-derive = { version = "0.1.0", path = "crates/src-derive", registry = "oksoftware" }
|
||||
paste = "1.0.15"
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.38.0"
|
||||
|
|
|
@ -9,3 +9,7 @@ okstd = { version = "0.1.9", registry = "oksoftware", features = ["macros"] }
|
|||
|
||||
src-derive = { version = "0.1.0", path = "../src-derive", registry = "oksoftware" }
|
||||
srclang = { version = "0.1.0", path = "../..", registry = "oksoftware" }
|
||||
|
||||
# [[bin]]
|
||||
# name = "src-derive-test"
|
||||
# path = "expanded.rs"
|
File diff suppressed because it is too large
Load diff
|
@ -1,25 +1,33 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use src_derive::node;
|
||||
use srclang::lexer::Location;
|
||||
use srclang::ops;
|
||||
use srclang::parser::span::Spanned;
|
||||
use srclang::span;
|
||||
use std::fmt::Display;
|
||||
use std::ops::Range;
|
||||
|
||||
#[node]
|
||||
struct Ident {
|
||||
name: String,
|
||||
generics: Vec<Ident>,
|
||||
}
|
||||
use okstd::prelude::*;
|
||||
use src_derive::visitor;
|
||||
use srclang::{lexer::Location, Db};
|
||||
use std::{fmt::Display, ops::Range};
|
||||
|
||||
pub const ANON_FN_NAME: &str = "anonymous";
|
||||
use srclang::parser::span::*;
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Ident(pub String, pub Option<Vec<Spanned<Ident>>>);
|
||||
|
||||
impl Display for Ident {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
#[node]
|
||||
struct Field {
|
||||
vis: Option<Visibility>,
|
||||
name: String,
|
||||
ty: Ident,
|
||||
}
|
||||
#[derive(PartialEq, Debug, Clone, Default)]
|
||||
|
||||
pub enum Literal {
|
||||
Bool(bool),
|
||||
Float(f64),
|
||||
Integer(i64),
|
||||
String(String),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Visibility {
|
||||
#[default]
|
||||
Private,
|
||||
Public,
|
||||
}
|
||||
|
@ -33,329 +41,79 @@ impl Display for Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct StringLit(pub String);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Binding(pub Spanned<Ident>, pub Box<Spanned<Node>>);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Literal {
|
||||
Bool(bool),
|
||||
Float(f64),
|
||||
Integer(i64),
|
||||
String(String),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Keyword {
|
||||
None,
|
||||
Some,
|
||||
Let,
|
||||
Public,
|
||||
Private,
|
||||
Fn,
|
||||
If,
|
||||
Else,
|
||||
Match,
|
||||
Arrow,
|
||||
Struct,
|
||||
SelfValue,
|
||||
When,
|
||||
Effect,
|
||||
Impl,
|
||||
Use,
|
||||
From,
|
||||
Where,
|
||||
Self_,
|
||||
}
|
||||
|
||||
impl Display for Keyword {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let kw = match self {
|
||||
Keyword::None => "none",
|
||||
Keyword::Some => "some",
|
||||
Keyword::Let => "let",
|
||||
Keyword::Fn => "fn",
|
||||
Keyword::If => "if",
|
||||
Keyword::Else => "else",
|
||||
Keyword::Match => "match",
|
||||
Keyword::Arrow => "=>",
|
||||
Keyword::Struct => "struct",
|
||||
Keyword::SelfValue => "self",
|
||||
Keyword::When => "when",
|
||||
Keyword::Effect => "effect",
|
||||
Keyword::Impl => "impl",
|
||||
Keyword::Use => "use",
|
||||
Keyword::From => "from",
|
||||
Keyword::Where => "where",
|
||||
Keyword::Self_ => "Self",
|
||||
Keyword::Public => "pub",
|
||||
Keyword::Private => "priv",
|
||||
};
|
||||
write!(f, "{}", kw)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Value {
|
||||
Literal(Literal),
|
||||
Ident(Ident),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Block<T>(pub Vec<T>);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Tuple<T>(pub Vec<T>);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Array<T>(pub Vec<T>);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct BinaryOperation {
|
||||
pub lhs: Box<Spanned<Node>>,
|
||||
pub op: Operator,
|
||||
pub rhs: Box<Spanned<Node>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FnCall(pub Spanned<Ident>, pub Vec<Spanned<Node>>);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Node {
|
||||
BinaryExpression(BinaryOperation),
|
||||
Bool(bool),
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
Ident(Spanned<Ident>),
|
||||
Binding(Binding),
|
||||
FnCall(FnCall),
|
||||
String(String),
|
||||
FnDef(FnDef),
|
||||
EffectDef(EffectDef),
|
||||
StructDef(StructDef),
|
||||
UseDef(UseDef),
|
||||
Keyword(Keyword),
|
||||
ImplDef(ImplDef),
|
||||
Branch(BranchDef),
|
||||
FieldAccess(FieldAccess),
|
||||
Visibility(Visibility),
|
||||
Error,
|
||||
}
|
||||
|
||||
impl Display for Node {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Node::BinaryExpression(bin) => write!(f, "{} {} {}", bin.lhs, bin.op, bin.rhs),
|
||||
Node::Bool(b) => write!(f, "{}", b),
|
||||
Node::Integer(i) => write!(f, "{}", i),
|
||||
Node::Float(fl) => write!(f, "{}", fl),
|
||||
Node::Ident(ident) => write!(f, "{}", ident.1),
|
||||
Node::Binding(bind) => write!(f, "{} = {}", bind.0, bind.1),
|
||||
Node::FnCall(call) => write!(
|
||||
f,
|
||||
"{}({})",
|
||||
call.0,
|
||||
call.1
|
||||
.iter()
|
||||
.map(|e| e.1.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
),
|
||||
Node::String(s) => write!(f, "{}", s),
|
||||
Node::FnDef(def) => write!(f, "{}", def.0),
|
||||
Node::EffectDef(def) => write!(f, "{}", def.0),
|
||||
Node::StructDef(def) => write!(f, "{}", def.0),
|
||||
Node::UseDef(def) => write!(f, "{:#?}", def.0),
|
||||
Node::Keyword(kw) => write!(f, "{}", kw),
|
||||
Node::ImplDef(def) => write!(f, "{}", def.0),
|
||||
Node::Branch(branch) => write!(f, "{}", branch.0),
|
||||
Node::FieldAccess(access) => write!(f, "{}.{}", access.0, access.1),
|
||||
Node::Visibility(vis) => write!(f, "{}", vis),
|
||||
Node::Error => write!(f, "Error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum FnArg {
|
||||
Reciever,
|
||||
Field(Spanned<FieldDef>),
|
||||
}
|
||||
|
||||
impl Display for FnArg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
FnArg::Reciever => write!(f, "self"),
|
||||
FnArg::Field(field) => write!(f, "{}", field.1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Prototype {
|
||||
pub name: Spanned<Ident>,
|
||||
pub args: Vec<Spanned<FnArg>>,
|
||||
pub ret: Option<Spanned<Ident>>,
|
||||
pub effects: Vec<Spanned<Ident>>,
|
||||
}
|
||||
|
||||
impl Display for Prototype {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}(", self.name)?;
|
||||
for arg in self.args.iter() {
|
||||
write!(f, "{}", arg)?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
if let Some(ret) = &self.ret {
|
||||
write!(f, " -> {}", ret)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Whitespace {
|
||||
Space,
|
||||
Tab,
|
||||
Newline,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Operator {
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Modulo,
|
||||
Increment,
|
||||
Decrement,
|
||||
Maybe,
|
||||
Mod,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
Neg,
|
||||
Dot,
|
||||
Arrow,
|
||||
FatArrow,
|
||||
DoubleColon,
|
||||
Eq,
|
||||
Ne,
|
||||
Lt,
|
||||
Le,
|
||||
Gt,
|
||||
Ge,
|
||||
}
|
||||
|
||||
impl Display for Operator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let op = match self {
|
||||
Operator::Add => "+",
|
||||
Operator::Sub => "-",
|
||||
Operator::Mul => "*",
|
||||
Operator::Div => "/",
|
||||
Operator::Modulo => "%",
|
||||
Operator::Increment => "++",
|
||||
Operator::Decrement => "--",
|
||||
Operator::Maybe => "?",
|
||||
Operator::Not => "!",
|
||||
Operator::Neg => "-",
|
||||
Operator::Dot => ".",
|
||||
Operator::Arrow => "->",
|
||||
Operator::FatArrow => "=>",
|
||||
Operator::DoubleColon => "::",
|
||||
};
|
||||
write!(f, "{}", op)
|
||||
struct PrettyPrinter;
|
||||
|
||||
impl FieldVisitor for PrettyPrinter {
|
||||
fn visit_vis(&self, vis: &Visibility, range: &Range<Location>) -> ops::traversal::Result {
|
||||
print!("{} ", vis);
|
||||
ops::traversal::Result::Continue
|
||||
}
|
||||
|
||||
fn visit_name(&self, name: &String, range: &Range<Location>) -> ops::traversal::Result {
|
||||
print!("{} :", name);
|
||||
ops::traversal::Result::Continue
|
||||
}
|
||||
|
||||
fn visit_ty(&self, ty: &Ident, range: &Range<Location>) -> ops::traversal::Result {
|
||||
ty.accept(self);
|
||||
ops::traversal::Result::Continue
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FieldAccess(pub Box<Spanned<Node>>, pub Box<Spanned<Node>>);
|
||||
impl IdentVisitor for PrettyPrinter {
|
||||
fn visit_name(&self, name: &String, range: &Range<Location>) -> ops::traversal::Result {
|
||||
print!("{}", name);
|
||||
ops::traversal::Result::Continue
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Module(pub Vec<Spanned<Node>>);
|
||||
|
||||
// defs
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FieldDef(
|
||||
pub Spanned<Visibility>,
|
||||
pub Spanned<Ident>,
|
||||
pub Spanned<Ident>,
|
||||
);
|
||||
|
||||
impl Display for FieldDef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}: {}", self.0, self.1)
|
||||
fn visit_generics(&self, generic: &Ident, range: &Range<Location>) -> ops::traversal::Result {
|
||||
print!("<");
|
||||
generic.accept(self);
|
||||
print!(">");
|
||||
ops::traversal::Result::Continue
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct StructDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<Ident>,
|
||||
pub Block<Spanned<FieldDef>>,
|
||||
);
|
||||
fn main() {
|
||||
let b = Ident::new(
|
||||
span!(Location::default(), "b".to_string(), Location::default()),
|
||||
vec![span!(
|
||||
Location::default(),
|
||||
Ident::new(
|
||||
span!(Location::default(), "c".to_string(), Location::default()),
|
||||
vec![]
|
||||
),
|
||||
Location::default()
|
||||
)],
|
||||
);
|
||||
let a = Field::new(
|
||||
Some(span!(
|
||||
Location::default(),
|
||||
Visibility::Public,
|
||||
Location::default()
|
||||
)),
|
||||
span!(Location::default(), "a".to_string(), Location::default()),
|
||||
span!(Location::default(), b, Location::default()),
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FnIdent(pub Ident);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct EffectDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<Ident>,
|
||||
pub Vec<Spanned<Ident>>,
|
||||
pub Block<Spanned<Prototype>>,
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct UseDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Vec<Spanned<Ident>>,
|
||||
pub Spanned<Ident>,
|
||||
);
|
||||
|
||||
impl Display for UseDef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} {:?} from {}", self.0, self.1, self.2)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct KeywordAndVisibility(pub Spanned<Keyword>, pub Spanned<Visibility>);
|
||||
|
||||
impl Display for KeywordAndVisibility {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} {}", self.1, self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct ImplDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<Ident>,
|
||||
pub Option<Spanned<Ident>>,
|
||||
pub Block<Spanned<Node>>,
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct BranchDef(
|
||||
pub Box<Spanned<Node>>,
|
||||
pub Vec<(Spanned<Node>, Block<Spanned<Node>>)>,
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FnDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<Prototype>,
|
||||
pub Block<Spanned<Node>>,
|
||||
pub Vec<(Spanned<Ident>, Block<Spanned<Node>>)>,
|
||||
);
|
||||
|
||||
impl Display for FnDef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} {} {{", self.0, self.1)?;
|
||||
for expr in self.2 .0.iter() {
|
||||
write!(f, "{}", expr)?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
trait Visitor {
|
||||
fn visit_module(&mut self, module: &Module, span: Range<Location>);
|
||||
fn visit_block(&mut self, block: &Block<Spanned<Node>>, span: Range<Location>);
|
||||
let pretty_printer = PrettyPrinter;
|
||||
a.accept(&pretty_printer);
|
||||
println!("");
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
use proc_macro::TokenStream;
|
||||
mod visitor;
|
||||
mod node;
|
||||
mod walker;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn visitor(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
TokenStream::from(visitor::generate_visitor_trait(item))
|
||||
pub fn node(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
TokenStream::from(node::define_nodes(_attr, item))
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn walker(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
TokenStream::from(walker::generate_walker_impl(item))
|
||||
}
|
||||
|
|
346
crates/src-derive/src/node.rs
Normal file
346
crates/src-derive/src/node.rs
Normal file
|
@ -0,0 +1,346 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use syn::{
|
||||
parse_macro_input, Data, DeriveInput, Fields, GenericArgument, Ident, PathArguments, Type,
|
||||
TypePath,
|
||||
};
|
||||
|
||||
pub fn define_nodes(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(item as DeriveInput);
|
||||
|
||||
let struct_name = &input.ident;
|
||||
let fields = match &input.data {
|
||||
Data::Struct(data) => &data.fields,
|
||||
_ => {
|
||||
return quote! {
|
||||
compile_error!("define_nodes can only be used on structs");
|
||||
}
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
let spanned_fields = fields.iter().map(|field| {
|
||||
let field_name = &field.ident;
|
||||
let field_type = &field.ty;
|
||||
match field_type {
|
||||
Type::Path(path) => {
|
||||
let expanded_type = wrap_path_in_spanned(path);
|
||||
quote! {
|
||||
#field_name: #expanded_type,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"Only named fields are supported which {} is not",
|
||||
field_type.into_token_stream()
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let expanded_impl = fields.iter().map(|field| {
|
||||
let field_name = &field.ident;
|
||||
let field_span_getter = format_ident!("{}_span", field_name.as_ref().unwrap());
|
||||
let field_node_getter = format_ident!("{}_node", field_name.as_ref().unwrap());
|
||||
let field_type = &field.ty;
|
||||
match field_type {
|
||||
Type::Path(path) => {
|
||||
let expanded_type = wrap_path_in_spanned(path);
|
||||
let expanded_range_type = wrap_range_location(path);
|
||||
quote! {
|
||||
fn #field_node_getter(&self) -> &#expanded_type {
|
||||
todo!()
|
||||
}
|
||||
fn #field_span_getter(&self) -> &#expanded_range_type {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"Only named fields are supported which {} is not",
|
||||
field_type.into_token_stream()
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let visitor_name = format_ident!("{}Visitor", struct_name);
|
||||
let visitor_trait_stub = fields.iter().map(|field| {
|
||||
let field_name = &field.ident;
|
||||
let field_visit = format_ident!("visit_{}", field_name.as_ref().unwrap());
|
||||
let field_type = &field.ty;
|
||||
match field_type {
|
||||
Type::Path(path) => {
|
||||
let unwrapped_type = unwrap_path(path);
|
||||
quote! {
|
||||
fn #field_visit(&self, node: &#unwrapped_type, span: &Range<Location>) -> ops::traversal::Result;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"Only named fields are supported which {} is not",
|
||||
field_type.into_token_stream()
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let accept_impl = fields.iter().map(|field| {
|
||||
let field_name = &field.ident;
|
||||
let field_type = &field.ty;
|
||||
match field_type {
|
||||
Type::Path(path) => {
|
||||
let visit_fn = format_ident!("visit_{}", field_name.as_ref().unwrap());
|
||||
match path.path.segments.last() {
|
||||
Some(syn::PathSegment { ident, arguments }) => match arguments {
|
||||
PathArguments::None => {
|
||||
quote! {
|
||||
if let cont = visitor.#visit_fn(
|
||||
&self.#field_name.1,
|
||||
&(self.#field_name.0..self.#field_name.2)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
PathArguments::AngleBracketed(args) => match args.args.first() {
|
||||
Some(GenericArgument::Type(_)) => match ident.to_string().as_str() {
|
||||
"Option" => {
|
||||
quote! {
|
||||
if let Some(inner) = &self.#field_name {
|
||||
if let cont = visitor.#visit_fn(
|
||||
&inner.1,
|
||||
&(inner.0..inner.2)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"Vec" => {
|
||||
quote! {
|
||||
for inner in self.#field_name.iter() {
|
||||
if let cont = visitor.#visit_fn(
|
||||
&inner.1,
|
||||
&(inner.0..inner.2)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
if let cont =visitor.#visit_fn(
|
||||
&self.#field_name.1,
|
||||
&(self.#field_name.0..self.#field_name.2)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
quote! {
|
||||
if let cont = visitor.#visit_fn(
|
||||
self.1,
|
||||
self.0..self.2
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
PathArguments::Parenthesized(_) => todo!(),
|
||||
},
|
||||
None => {
|
||||
quote! {
|
||||
compile_error!("No path segments found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"Only named fields are supported which {} is not",
|
||||
field_type.into_token_stream()
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let field_names = fields.iter().map(|field| {
|
||||
let field_name = &field.ident;
|
||||
quote! {
|
||||
#field_name
|
||||
}
|
||||
});
|
||||
let not_spanned_fileds = spanned_fields.clone();
|
||||
let field_types = fields.iter().map(|field| {
|
||||
let field_type = &field.ty;
|
||||
match field_type {
|
||||
Type::Path(path) => {
|
||||
let expanded_type = wrap_path_in_spanned(path);
|
||||
quote! {
|
||||
#expanded_type
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"Only named fields are supported which {} is not",
|
||||
field_type.into_token_stream()
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
let field_types_clone = field_types.clone();
|
||||
let struct_name_lower = format_ident!("{}", struct_name.to_string().to_lowercase());
|
||||
let field_ids = fields.iter().enumerate().map(|field| {
|
||||
let field_name = syn::Index::from(field.0);
|
||||
quote! {
|
||||
#struct_name_lower.#field_name
|
||||
}
|
||||
});
|
||||
let vis = &input.vis;
|
||||
let expanded = quote! {
|
||||
#[derive(Debug)]
|
||||
#vis struct #struct_name {
|
||||
#(#spanned_fields)*
|
||||
}
|
||||
#vis trait #visitor_name {
|
||||
#(#visitor_trait_stub)*
|
||||
}
|
||||
impl From<
|
||||
(#(#field_types),*)
|
||||
> for #struct_name {
|
||||
fn from(
|
||||
#struct_name_lower: (
|
||||
#(#field_types_clone),*
|
||||
)
|
||||
) -> Self {
|
||||
Self::new(
|
||||
#(#field_ids),*
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl #struct_name {
|
||||
fn new(#(#not_spanned_fileds)*) -> Self {
|
||||
Self {
|
||||
#(#field_names,)*
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
impl #struct_name {
|
||||
fn accept(&self, visitor: &impl #visitor_name) {
|
||||
#(#accept_impl)*
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
fn wrap_range_location(path: &TypePath) -> impl ToTokens {
|
||||
match path.path.segments.last() {
|
||||
Some(syn::PathSegment { ident, arguments }) => {
|
||||
if let syn::PathArguments::AngleBracketed(args) = arguments {
|
||||
if let Some(GenericArgument::Type(inner_ty)) = args.args.first() {
|
||||
quote! {
|
||||
#ident<Range<Location>>
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
Range<Location>
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
Range<Location>
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
Range<Location>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_path_in_spanned(path: &TypePath) -> impl ToTokens {
|
||||
match path.path.segments.last() {
|
||||
Some(syn::PathSegment { ident, arguments }) => {
|
||||
if let syn::PathArguments::AngleBracketed(args) = arguments {
|
||||
if let Some(GenericArgument::Type(inner_ty)) = args.args.first() {
|
||||
quote! {
|
||||
#ident<Spanned<#inner_ty>>
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
Spanned<#ident>
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
Spanned<#ident>
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
Spanned<#path>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrap_path(path: &TypePath) -> impl ToTokens {
|
||||
match path.path.segments.last() {
|
||||
Some(syn::PathSegment { ident, arguments }) => {
|
||||
if let syn::PathArguments::AngleBracketed(args) = arguments {
|
||||
if let Some(GenericArgument::Type(inner_ty)) = args.args.first() {
|
||||
quote! {
|
||||
#inner_ty
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#ident
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#ident
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
#path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_type_in_spanned(ty: &Type, field_name: &Option<Ident>) -> impl ToTokens {
|
||||
match (ty, field_name) {
|
||||
(Type::Path(path), Some(field_name)) => {
|
||||
let ty = wrap_path_in_spanned(path);
|
||||
quote! {
|
||||
#field_name: #ty,
|
||||
}
|
||||
}
|
||||
(Type::Path(path), None) => {
|
||||
let ty = wrap_path_in_spanned(path);
|
||||
quote! {
|
||||
#ty,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
compile_error!("Only named fields are supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
source: crates/src-derive/src/lib.rs
|
||||
assertion_line: 157
|
||||
expression: expected.to_string()
|
||||
---
|
||||
pub trait BinaryOperationVisitor : BoxVisitor + SpannedVisitor + NodeVisitor + OperatorVisitor { fn visit (& mut self , node : & BinaryOperation) { self . visit_lhs (& node . lhs) ; self . visit_op (& node . op) ; self . visit_rhs (& node . rhs) ; } fn visit_lhs (& mut self , value : & Box < Spanned < Node >>) { } fn visit_op (& mut self , value : & Operator) { } fn visit_rhs (& mut self , value : & Box < Spanned < Node >>) { } }
|
|
@ -1,83 +0,0 @@
|
|||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{parse_macro_input, DeriveInput, Data, Fields};
|
||||
|
||||
|
||||
pub fn generate_visitor_trait(stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let item = proc_macro::TokenStream::from(stream);
|
||||
let input = parse_macro_input!(item as DeriveInput);
|
||||
let struct_name = input.ident;
|
||||
|
||||
let visitor_trait_name = format_ident!("{}Visitor", struct_name);
|
||||
|
||||
let field_types: Vec<syn::Type> = match input.data {
|
||||
Data::Struct(data_struct) => match data_struct.fields {
|
||||
Fields::Named(fields) => fields.named.into_iter().map(|field| field.ty).collect(),
|
||||
Fields::Unnamed(fields) => fields.unnamed.into_iter().map(|field| field.ty).collect(),
|
||||
Fields::Unit => vec![],
|
||||
},
|
||||
_ => panic!("visitor macro only supports structs"),
|
||||
};
|
||||
|
||||
let field_visitor_traits = field_types.iter().map(|ty| {
|
||||
let ty_str = quote!(#ty).to_string();
|
||||
let visitor_trait_name = format_ident!("{}Visitor", ty_str);
|
||||
quote! { + #visitor_trait_name }
|
||||
});
|
||||
|
||||
let visitor_methods = field_types.iter().map(|ty| {
|
||||
let ty_str = quote!(#ty).to_string();
|
||||
let method_name = format_ident!("visit_{}", ty_str);
|
||||
quote! {
|
||||
fn #method_name(self, node: #ty, span: Range<Location>);
|
||||
}
|
||||
});
|
||||
|
||||
let expanded = quote! {
|
||||
trait #visitor_trait_name: NodeVisitor #(#field_visitor_traits)* {
|
||||
#(#visitor_methods)*
|
||||
}
|
||||
};
|
||||
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_visitor() {
|
||||
let input = quote! {
|
||||
#[visitor]
|
||||
pub struct Test {
|
||||
field1: Spanned<Ident>,
|
||||
field2: Option<Spanned<Ident>>,
|
||||
field3: Box<Spanned<Ident>>,
|
||||
field4: Vec<Spanned<Ident>>,
|
||||
field5: Block<Spanned<Ident>>,
|
||||
}
|
||||
};
|
||||
|
||||
let expected = quote! {
|
||||
pub trait TestVisitor {
|
||||
fn visit_ident_field(&mut self, value: Ident, span: &Span);
|
||||
fn visit_ident_field2(&mut self, value: Option<Ident>, span: &Span);
|
||||
fn visit_ident_field3(&mut self, value: Ident, span: &Span);
|
||||
fn visit_ident_field4(&mut self, value: Vec<Ident>, span: &Span);
|
||||
fn visit_ident_field5(&mut self, value: Block<Ident>, span: &Span);
|
||||
}
|
||||
|
||||
pub struct Test {
|
||||
field1: Spanned<Ident>,
|
||||
field2: Option<Spanned<Ident>>,
|
||||
field3: Box<Spanned<Ident>>,
|
||||
field4: Vec<Spanned<Ident>>,
|
||||
field5: Block<Spanned<Ident>>,
|
||||
}
|
||||
};
|
||||
|
||||
let actual = visitor(TokenStream::new(), input).to_string();
|
||||
assert_eq!(expected.to_string(), actual);
|
||||
}
|
||||
}
|
179
crates/src-derive/src/walker.rs
Normal file
179
crates/src-derive/src/walker.rs
Normal file
|
@ -0,0 +1,179 @@
|
|||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use syn::{
|
||||
parse_macro_input, Data, DeriveInput, Fields, GenericArgument, PathArguments, Type, TypePath,
|
||||
};
|
||||
|
||||
pub fn generate_walker_impl(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(item as DeriveInput);
|
||||
let type_name = &input.ident;
|
||||
let walker_name = format_ident!("{}Walker", type_name);
|
||||
let visitor_name = format_ident!("{}Visitor", type_name);
|
||||
|
||||
let walk_impl = generate_walk_impl(type_name, &input.data);
|
||||
|
||||
let expanded = quote! {
|
||||
#input
|
||||
|
||||
pub struct #walker_name;
|
||||
|
||||
impl #walker_name {
|
||||
pub fn walk<V: #visitor_name>(node: &Spanned<#type_name>, visitor: &mut V) {
|
||||
#walk_impl
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
fn generate_walk_impl(type_name: &Ident, data: &Data) -> TokenStream {
|
||||
match data {
|
||||
Data::Struct(data_struct) => generate_struct_walk_impl(data_struct),
|
||||
Data::Enum(data_enum) => generate_enum_walk_impl(type_name, data_enum),
|
||||
Data::Union(_) => panic!("Unions are not supported"),
|
||||
}
|
||||
}
|
||||
fn generate_field_visit(ty: &Type, field_access: TokenStream) -> TokenStream {
|
||||
match ty {
|
||||
Type::Path(TypePath { path, .. }) => {
|
||||
if let Some(segment) = path.segments.last() {
|
||||
match segment.ident.to_string().as_str() {
|
||||
"Spanned" => {
|
||||
if let PathArguments::AngleBracketed(args) = &segment.arguments {
|
||||
if let Some(GenericArgument::Type(inner_type)) = args.args.first() {
|
||||
let visit_method = format_ident!(
|
||||
"visit_{}",
|
||||
inner_type.to_token_stream().to_string().to_lowercase()
|
||||
);
|
||||
return quote! {
|
||||
visitor.#visit_method(&(#field_access).1, (#field_access).span());
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
"Box" => {
|
||||
if let PathArguments::AngleBracketed(args) = &segment.arguments {
|
||||
if let Some(GenericArgument::Type(inner_type)) = args.args.first() {
|
||||
let inner_visit =
|
||||
generate_field_visit(inner_type, quote! { (*#field_access) });
|
||||
return quote! {
|
||||
#inner_visit
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
"Option" => {
|
||||
if let PathArguments::AngleBracketed(args) = &segment.arguments {
|
||||
if let Some(GenericArgument::Type(inner_type)) = args.args.first() {
|
||||
let inner_visit =
|
||||
generate_field_visit(inner_type, quote! { inner });
|
||||
return quote! {
|
||||
if let Some(inner) = #field_access.as_ref() {
|
||||
#inner_visit
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
"Vec" => {
|
||||
if let PathArguments::AngleBracketed(args) = &segment.arguments {
|
||||
if let Some(GenericArgument::Type(inner_type)) = args.args.first() {
|
||||
let inner_visit = generate_field_visit(inner_type, quote! { item });
|
||||
return quote! {
|
||||
for item in #field_access.iter() {
|
||||
#inner_visit
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
quote! {}
|
||||
}
|
||||
|
||||
fn generate_struct_walk_impl(data_struct: &syn::DataStruct) -> TokenStream {
|
||||
let field_visits = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let field_name = &field.ident;
|
||||
generate_field_visit(&field.ty, quote!(node.1.#field_name))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
#(#field_visits)*
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_enum_walk_impl(enum_name: &Ident, data_enum: &syn::DataEnum) -> TokenStream {
|
||||
let variant_matches = data_enum
|
||||
.variants
|
||||
.iter()
|
||||
.map(|variant| {
|
||||
let variant_name = &variant.ident;
|
||||
|
||||
match &variant.fields {
|
||||
Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
|
||||
let field_visit = generate_field_visit(&fields.unnamed[0].ty, quote!(value));
|
||||
quote! {
|
||||
#enum_name::#variant_name(value) => {
|
||||
#field_visit
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => quote! {
|
||||
#enum_name::#variant_name { .. } => {}
|
||||
},
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
match &node.1 {
|
||||
#(#variant_matches)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_spanned_type(ty: &Type) -> bool {
|
||||
if let Type::Path(TypePath { path, .. }) = ty {
|
||||
if let Some(segment) = path.segments.last() {
|
||||
return segment.ident == "Spanned";
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_box_type(ty: &Type) -> bool {
|
||||
if let Type::Path(TypePath { path, .. }) = ty {
|
||||
if let Some(segment) = path.segments.last() {
|
||||
return segment.ident == "Box";
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_option_type(ty: &Type) -> bool {
|
||||
if let Type::Path(TypePath { path, .. }) = ty {
|
||||
if let Some(segment) = path.segments.last() {
|
||||
return segment.ident == "Option";
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_vec_type(ty: &Type) -> bool {
|
||||
if let Type::Path(TypePath { path, .. }) = ty {
|
||||
if let Some(segment) = path.segments.last() {
|
||||
return segment.ident == "Vec";
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
72390
expanded.ast.rs
Normal file
72390
expanded.ast.rs
Normal file
File diff suppressed because it is too large
Load diff
72292
src/ast/expanded.ast.rs
Normal file
72292
src/ast/expanded.ast.rs
Normal file
File diff suppressed because it is too large
Load diff
72293
src/ast/expanded.rs
Normal file
72293
src/ast/expanded.rs
Normal file
File diff suppressed because it is too large
Load diff
71
src/ast/mod.rs
Normal file
71
src/ast/mod.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use crate::lexer::Location;
|
||||
use crate::ops;
|
||||
use crate::parser::span::Spanned;
|
||||
use src_derive::node;
|
||||
use std::fmt::Display;
|
||||
use std::ops::Range;
|
||||
|
||||
/// ast node representing an identifier.
|
||||
#[node]
|
||||
pub struct Ident {
|
||||
name: String,
|
||||
generics: Vec<Ident>,
|
||||
}
|
||||
|
||||
/// ast node representing a field.
|
||||
#[node]
|
||||
pub struct Field {
|
||||
vis: Option<Visibility>,
|
||||
name: String,
|
||||
ty: Ident,
|
||||
}
|
||||
|
||||
/// An enum representing the different types of literals that can be used in an expression.
|
||||
pub enum Literal {
|
||||
Bool(bool),
|
||||
Float(f64),
|
||||
Integer(i64),
|
||||
String(String),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// An enum representing the visibility of a field or method.
|
||||
pub enum Visibility {
|
||||
Private,
|
||||
Public,
|
||||
}
|
||||
|
||||
impl Display for Visibility {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Visibility::Public => write!(f, "pub"),
|
||||
Visibility::Private => write!(f, "priv"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An enum representing the different operators that can be used in an expression.
|
||||
pub enum Operator {
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
Eq,
|
||||
Ne,
|
||||
Lt,
|
||||
Le,
|
||||
Gt,
|
||||
Ge,
|
||||
}
|
||||
|
||||
pub enum Node {
|
||||
Ident(Ident),
|
||||
Field(Field),
|
||||
Literal(Literal),
|
||||
Visibility(Visibility),
|
||||
Operator(Operator),
|
||||
}
|
48
src/lib.rs
48
src/lib.rs
|
@ -1,6 +1,8 @@
|
|||
pub mod analyzer;
|
||||
pub mod ast;
|
||||
pub mod compiler;
|
||||
pub mod lexer;
|
||||
pub mod ops;
|
||||
pub mod parser;
|
||||
|
||||
use compiler::text;
|
||||
|
@ -39,49 +41,3 @@ pub struct Jar(
|
|||
pub trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
impl<DB> Db for DB where DB: ?Sized + salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! visitor {
|
||||
($(#[$meta:meta])* $vis:vis struct $name:ident($($field:ident: $ty:ty),*);) => {
|
||||
$(#[$meta])*
|
||||
$vis struct $name($($field: $ty),*);
|
||||
|
||||
paste::paste! {
|
||||
trait [<$name Visitor>] {
|
||||
$(
|
||||
visitor!(@visit $field, $ty);
|
||||
)*
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(@visit $field:ident, Spanned<$t:ty>) => {
|
||||
paste::paste! {
|
||||
fn [<visit_ $t:snake _field>](&mut self, $t, Range<Location>);
|
||||
}
|
||||
};
|
||||
|
||||
(@visit $field:ident, Option<Spanned<$t:ty>>) => {
|
||||
paste::paste! {
|
||||
fn [<visit_ $t:snake _field>](&mut self, Option<$t>, Range<Location>);
|
||||
}
|
||||
};
|
||||
|
||||
(@visit $field:ident, Box<Spanned<$t:ty>>) => {
|
||||
paste::paste! {
|
||||
fn [<visit_ $t:snake _field>](&mut self, $t, Range<Location>);
|
||||
}
|
||||
};
|
||||
|
||||
(@visit $field:ident, Vec<Spanned<$t:ty>>) => {
|
||||
paste::paste! {
|
||||
fn [<visit_ $t:snake _field>](&mut self, $t, Range<Location>);
|
||||
}
|
||||
};
|
||||
|
||||
(@visit $field:ident, Block<Spanned<$t:ty>>) => {
|
||||
paste::paste! {
|
||||
fn [<visit_ $t:snake _field>](&mut self, $t, Range<Location>);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
10
src/ops/mod.rs
Normal file
10
src/ops/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
/// This module contains the srclang ops.
|
||||
pub mod traversal {
|
||||
/// The result of a traversal operation.
|
||||
pub enum Result {
|
||||
/// Continue the traversal.
|
||||
Continue,
|
||||
/// Stop the traversal.
|
||||
Break,
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
use std::fmt::Display;
|
||||
use std::{fmt::Display, ops::Range};
|
||||
pub const ANON_FN_NAME: &str = "anonymous";
|
||||
|
||||
use crate::visitor;
|
||||
use super::span;
|
||||
use super::span::*;
|
||||
use src_derive::node;
|
||||
|
||||
use super::span::*;
|
||||
|
||||
|
@ -13,6 +14,7 @@ impl Display for Ident {
|
|||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Default)]
|
||||
pub enum Visibility {
|
||||
#[default]
|
||||
|
@ -20,8 +22,6 @@ pub enum Visibility {
|
|||
Public,
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Display for Visibility {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
@ -34,7 +34,6 @@ impl Display for Visibility {
|
|||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct StringLit(pub String);
|
||||
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct Binding(pub Spanned<Ident>, pub Box<Spanned<Node>>);
|
||||
|
||||
|
@ -69,6 +68,8 @@ pub enum Keyword {
|
|||
Self_,
|
||||
}
|
||||
|
||||
trait KeywordVisitor {}
|
||||
|
||||
impl Display for Keyword {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let kw = match self {
|
||||
|
@ -284,7 +285,7 @@ impl Display for FieldDef {
|
|||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct StructDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<KeywordAndVisibility>,
|
||||
pub Spanned<Ident>,
|
||||
pub Block<Spanned<FieldDef>>,
|
||||
);
|
||||
|
@ -294,7 +295,7 @@ pub struct FnIdent(pub Ident);
|
|||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct EffectDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<KeywordAndVisibility>,
|
||||
pub Spanned<Ident>,
|
||||
pub Vec<Spanned<Ident>>,
|
||||
pub Block<Spanned<Prototype>>,
|
||||
|
@ -302,7 +303,7 @@ pub struct EffectDef(
|
|||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct UseDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<KeywordAndVisibility>,
|
||||
pub Vec<Spanned<Ident>>,
|
||||
pub Spanned<Ident>,
|
||||
);
|
||||
|
@ -324,7 +325,7 @@ impl Display for KeywordAndVisibility {
|
|||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct ImplDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<KeywordAndVisibility>,
|
||||
pub Spanned<Ident>,
|
||||
pub Option<Spanned<Ident>>,
|
||||
pub Block<Spanned<Node>>,
|
||||
|
@ -336,12 +337,12 @@ pub struct BranchDef(
|
|||
pub Vec<(Spanned<Node>, Block<Spanned<Node>>)>,
|
||||
);
|
||||
|
||||
// #[visitor]
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct FnDef(
|
||||
pub KeywordAndVisibility,
|
||||
pub Spanned<KeywordAndVisibility>,
|
||||
pub Spanned<Prototype>,
|
||||
pub Block<Spanned<Node>>,
|
||||
pub Vec<(Spanned<Ident>, Block<Spanned<Node>>)>,
|
||||
);
|
||||
|
||||
impl Display for FnDef {
|
||||
|
@ -374,3 +375,26 @@ impl Arbitrary for Operator {
|
|||
}
|
||||
|
||||
impl Eq for Node {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::analyzer;
|
||||
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
|
||||
struct TestVisitor;
|
||||
|
||||
#[test]
|
||||
fn test_binding_vistior() {
|
||||
let input = "fn some()[] {let a = some_fnExpr(1, \"2\", 3)}";
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
assert!(errors.is_empty());
|
||||
assert!(t.is_ok());
|
||||
let t = t.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,111 +1,118 @@
|
|||
// use crate::{lexer::Coord, parser::errors::pretty_errors};
|
||||
// use insta::assert_snapshot;
|
||||
use crate::{analyzer, lexer::Location, parser::errors::pretty_errors};
|
||||
use insta::assert_snapshot;
|
||||
|
||||
#[cfg(test)]
|
||||
#[okstd::test]
|
||||
fn test_empty_parser() {
|
||||
use crate::analyzer;
|
||||
|
||||
// #[cfg(test)]
|
||||
// #[okstd::test]
|
||||
// fn test_empty_parser() {
|
||||
// let input = " ";
|
||||
// let mut errors = vec![];
|
||||
// let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
// let t: Result<crate::parser::ast::Module, lalrpop_util::ParseError<Coord, crate::lexer::Token, &str>> = crate::parser::src::SourceParser::new().parse(&mut errors, wrapper);
|
||||
// assert!(errors.is_empty());
|
||||
// let fmted = format!("{:#?}", t.unwrap());
|
||||
// assert_snapshot!(fmted, @r###"
|
||||
// Module(
|
||||
// [],
|
||||
// )
|
||||
// "###);
|
||||
// }
|
||||
let input = " ";
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
assert!(errors.is_empty());
|
||||
let fmted = format!("{:#?}", t.unwrap());
|
||||
assert_snapshot!(fmted, @r###"
|
||||
Module(
|
||||
[],
|
||||
)
|
||||
"###);
|
||||
}
|
||||
|
||||
// #[okstd::test]
|
||||
// fn test_fn_call_parser_with_multiple_args_and_strings() {
|
||||
// let input = "fn some()[] {let a = some_fnExpr(1, \"2\", 3)}";
|
||||
// let mut errors = vec![];
|
||||
// let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
// let t = crate::parser::src::SourceParser::new().parse(&mut errors, wrapper);
|
||||
// if !errors.is_empty() {
|
||||
// panic!("{}", pretty_errors(&input, errors));
|
||||
// }
|
||||
// assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
// }
|
||||
#[okstd::test]
|
||||
fn test_fn_call_parser_with_multiple_args_and_strings() {
|
||||
let input = "fn some()[] {let a = some_fnExpr(1, \"2\", 3)}";
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
if !errors.is_empty() {
|
||||
panic!("{}", pretty_errors(&input, errors));
|
||||
}
|
||||
assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
}
|
||||
|
||||
// #[okstd::test]
|
||||
// fn test_fn_def_parser() {
|
||||
// let input = r#"fn call(a:b, b:c) [throws, awaits, execs] {
|
||||
// call(1+1)
|
||||
// let a = 1
|
||||
// } when throws {
|
||||
// raise(1)
|
||||
// }"#;
|
||||
// let mut errors = vec![];
|
||||
// let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
// let t = crate::parser::src::SourceParser::new().parse(&mut errors, wrapper);
|
||||
// assert!(errors.is_empty());
|
||||
// assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
// }
|
||||
#[okstd::test]
|
||||
fn test_fn_def_parser() {
|
||||
let input = r#"fn call(a:b, b:c) [throws, awaits, execs] {
|
||||
call(1+1)
|
||||
let a = 1
|
||||
}"#;
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
if !errors.is_empty() {
|
||||
panic!("{}", pretty_errors(&input, errors));
|
||||
}
|
||||
assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
}
|
||||
|
||||
// #[okstd::test]
|
||||
// fn test_effect() {
|
||||
// let input = r#"effect VM: async + throws + execs {
|
||||
// catch() []
|
||||
// await<T>(f: Future<T>) [] -> T
|
||||
// exec(arg0: string, args: stringvec) []
|
||||
// }"#;
|
||||
// let mut errors = vec![];
|
||||
// let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
// let t = crate::parser::src::SourceParser::new().parse(&mut errors, wrapper);
|
||||
// assert!(errors.is_empty());
|
||||
// assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
// }
|
||||
#[okstd::test]
|
||||
fn test_effect() {
|
||||
let input = r#"effect VM: async + throws + execs {
|
||||
catch() []
|
||||
await<T>(f: Future<T>) [] -> T
|
||||
exec(arg0: string, args: stringvec) []
|
||||
}"#;
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
assert!(errors.is_empty());
|
||||
assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
}
|
||||
|
||||
// #[okstd::test]
|
||||
// fn test_struct_parser() {
|
||||
// let input = r#"struct VM {
|
||||
// a: string
|
||||
// b: string
|
||||
// }"#;
|
||||
// let mut errors = vec![];
|
||||
// let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
// let t = crate::parser::src::SourceParser::new().parse(&mut errors, wrapper);
|
||||
// assert!(errors.is_empty());
|
||||
// assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
// }
|
||||
#[okstd::test]
|
||||
fn test_struct_parser() {
|
||||
let input = r#"struct VM {
|
||||
a: string
|
||||
b: string
|
||||
}"#;
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
assert!(errors.is_empty());
|
||||
assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
}
|
||||
|
||||
// #[okstd::test]
|
||||
// fn test_enum_parser() {
|
||||
// let input = r#"use { exec } from host
|
||||
#[okstd::test]
|
||||
fn test_enum_parser() {
|
||||
let input = r#"use { exec } from host
|
||||
|
||||
// effect Make: async + throws + execs + reads + writes {
|
||||
// catch() [throws]
|
||||
// await<T>(f: Future<T>) [async, throws] -> T
|
||||
// exec(arg0: string, args: stringvec) [Make] -> i32
|
||||
// read(name: string) [reads] -> string
|
||||
// write(name: string, value: string) [writes]
|
||||
// }
|
||||
|
||||
// struct Local {
|
||||
// host: host
|
||||
// }
|
||||
|
||||
// impl Make for Local {
|
||||
// fn catch(self) [throws] {
|
||||
// }
|
||||
// fn await<T>(f: Future<T>) [async, trhows] -> T {
|
||||
// yield()
|
||||
// }
|
||||
// fn exec(self, arg0: string, args: vec<string>) [Vm] -> i32 {
|
||||
// self.host.read("jobserver").await
|
||||
// if self.host.exec(arg0, args).await {
|
||||
// raise(1)
|
||||
// }
|
||||
// }
|
||||
// }"#;
|
||||
// let mut errors: Vec<lalrpop_util::ErrorRecovery<Coord, crate::lexer::Token, &str>> = vec![];
|
||||
// let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
// let t = crate::parser::src::SourceParser::new().parse(&mut errors, wrapper);
|
||||
// if !errors.is_empty() {
|
||||
// panic!("{}", pretty_errors(&input, errors));
|
||||
// }
|
||||
// assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
// }
|
||||
effect Make: async + throws + execs + reads + writes {
|
||||
catch() [throws]
|
||||
await<T>(f: Future<T>) [async, throws] -> T
|
||||
exec(arg0: string, args: stringvec) [Make] -> i32
|
||||
read(name: string) [reads] -> string
|
||||
write(name: string, value: string) [writes]
|
||||
}
|
||||
|
||||
struct Local {
|
||||
host: host
|
||||
}
|
||||
|
||||
impl Make for Local {
|
||||
fn catch(self) [throws] {
|
||||
}
|
||||
fn await<T>(f: Future<T>) [async, trhows] -> T {
|
||||
yield()
|
||||
}
|
||||
fn exec(self, arg0: string, args: vec<string>) [Vm] -> i32 {
|
||||
self.host.read("jobserver").await
|
||||
if self.host.exec(arg0, args).await {
|
||||
raise(1)
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let mut errors = vec![];
|
||||
let wrapper = crate::lexer::TripleIterator::new(input);
|
||||
let db = analyzer::db::Database::default();
|
||||
let t = crate::parser::src::SourceParser::new().parse(&mut errors, &db, wrapper);
|
||||
if !errors.is_empty() {
|
||||
panic!("{}", pretty_errors(&input, errors));
|
||||
}
|
||||
assert_snapshot!(format!("{:#?}", t.unwrap()));
|
||||
}
|
||||
|
|
|
@ -5,43 +5,55 @@ expression: "format!(\"{:#?}\", t.unwrap())"
|
|||
Module(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
EffectDef(
|
||||
EffectDef(
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Effect,
|
||||
Coord {
|
||||
offset: 6,
|
||||
line: 0,
|
||||
col: 6,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Effect,
|
||||
Location {
|
||||
offset: 6,
|
||||
line: 0,
|
||||
col: 6,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
),
|
||||
),
|
||||
Location {
|
||||
offset: 6,
|
||||
line: 0,
|
||||
col: 6,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 7,
|
||||
line: 0,
|
||||
col: 7,
|
||||
|
@ -50,7 +62,7 @@ Module(
|
|||
"VM",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 9,
|
||||
line: 0,
|
||||
col: 9,
|
||||
|
@ -58,7 +70,7 @@ Module(
|
|||
),
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 11,
|
||||
line: 0,
|
||||
col: 11,
|
||||
|
@ -67,14 +79,14 @@ Module(
|
|||
"async",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 0,
|
||||
col: 16,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 19,
|
||||
line: 0,
|
||||
col: 19,
|
||||
|
@ -83,14 +95,14 @@ Module(
|
|||
"throws",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 25,
|
||||
line: 0,
|
||||
col: 25,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 28,
|
||||
line: 0,
|
||||
col: 28,
|
||||
|
@ -99,7 +111,7 @@ Module(
|
|||
"execs",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 33,
|
||||
line: 0,
|
||||
col: 33,
|
||||
|
@ -109,388 +121,388 @@ Module(
|
|||
Block(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 44,
|
||||
Location {
|
||||
offset: 40,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Prototype {
|
||||
name: Spanned(
|
||||
Coord {
|
||||
offset: 44,
|
||||
Location {
|
||||
offset: 40,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Ident(
|
||||
"catch",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 49,
|
||||
Location {
|
||||
offset: 45,
|
||||
line: 1,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
),
|
||||
args: [],
|
||||
ret: None,
|
||||
effects: [],
|
||||
},
|
||||
Coord {
|
||||
offset: 54,
|
||||
Location {
|
||||
offset: 50,
|
||||
line: 1,
|
||||
col: 18,
|
||||
col: 14,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 63,
|
||||
Location {
|
||||
offset: 55,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Prototype {
|
||||
name: Spanned(
|
||||
Coord {
|
||||
offset: 63,
|
||||
Location {
|
||||
offset: 55,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Ident(
|
||||
"await",
|
||||
Some(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 69,
|
||||
Location {
|
||||
offset: 61,
|
||||
line: 2,
|
||||
col: 14,
|
||||
col: 10,
|
||||
},
|
||||
Ident(
|
||||
"T",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 70,
|
||||
Location {
|
||||
offset: 62,
|
||||
line: 2,
|
||||
col: 15,
|
||||
col: 11,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 71,
|
||||
Location {
|
||||
offset: 63,
|
||||
line: 2,
|
||||
col: 16,
|
||||
col: 12,
|
||||
},
|
||||
),
|
||||
args: [
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 72,
|
||||
Location {
|
||||
offset: 64,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
Field(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 72,
|
||||
Location {
|
||||
offset: 64,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 72,
|
||||
Location {
|
||||
offset: 64,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 72,
|
||||
Location {
|
||||
offset: 64,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 72,
|
||||
Location {
|
||||
offset: 64,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
Ident(
|
||||
"f",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 73,
|
||||
Location {
|
||||
offset: 65,
|
||||
line: 2,
|
||||
col: 18,
|
||||
col: 14,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 75,
|
||||
Location {
|
||||
offset: 67,
|
||||
line: 2,
|
||||
col: 20,
|
||||
col: 16,
|
||||
},
|
||||
Ident(
|
||||
"Future",
|
||||
Some(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 82,
|
||||
Location {
|
||||
offset: 74,
|
||||
line: 2,
|
||||
col: 27,
|
||||
col: 23,
|
||||
},
|
||||
Ident(
|
||||
"T",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 83,
|
||||
Location {
|
||||
offset: 75,
|
||||
line: 2,
|
||||
col: 28,
|
||||
col: 24,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 84,
|
||||
Location {
|
||||
offset: 76,
|
||||
line: 2,
|
||||
col: 29,
|
||||
col: 25,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 84,
|
||||
Location {
|
||||
offset: 76,
|
||||
line: 2,
|
||||
col: 29,
|
||||
col: 25,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 84,
|
||||
Location {
|
||||
offset: 76,
|
||||
line: 2,
|
||||
col: 29,
|
||||
col: 25,
|
||||
},
|
||||
),
|
||||
],
|
||||
ret: Some(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 92,
|
||||
Location {
|
||||
offset: 84,
|
||||
line: 2,
|
||||
col: 37,
|
||||
col: 33,
|
||||
},
|
||||
Ident(
|
||||
"T",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 93,
|
||||
Location {
|
||||
offset: 85,
|
||||
line: 2,
|
||||
col: 38,
|
||||
col: 34,
|
||||
},
|
||||
),
|
||||
),
|
||||
effects: [],
|
||||
},
|
||||
Coord {
|
||||
offset: 93,
|
||||
Location {
|
||||
offset: 85,
|
||||
line: 2,
|
||||
col: 38,
|
||||
col: 34,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 102,
|
||||
Location {
|
||||
offset: 90,
|
||||
line: 3,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Prototype {
|
||||
name: Spanned(
|
||||
Coord {
|
||||
offset: 102,
|
||||
Location {
|
||||
offset: 90,
|
||||
line: 3,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Ident(
|
||||
"exec",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 106,
|
||||
Location {
|
||||
offset: 94,
|
||||
line: 3,
|
||||
col: 12,
|
||||
col: 8,
|
||||
},
|
||||
),
|
||||
args: [
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 107,
|
||||
Location {
|
||||
offset: 95,
|
||||
line: 3,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
Field(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 107,
|
||||
Location {
|
||||
offset: 95,
|
||||
line: 3,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 107,
|
||||
Location {
|
||||
offset: 95,
|
||||
line: 3,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 107,
|
||||
Location {
|
||||
offset: 95,
|
||||
line: 3,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 107,
|
||||
Location {
|
||||
offset: 95,
|
||||
line: 3,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
Ident(
|
||||
"arg0",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 111,
|
||||
Location {
|
||||
offset: 99,
|
||||
line: 3,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 113,
|
||||
Location {
|
||||
offset: 101,
|
||||
line: 3,
|
||||
col: 19,
|
||||
col: 15,
|
||||
},
|
||||
Ident(
|
||||
"string",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 119,
|
||||
Location {
|
||||
offset: 107,
|
||||
line: 3,
|
||||
col: 25,
|
||||
col: 21,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 119,
|
||||
Location {
|
||||
offset: 107,
|
||||
line: 3,
|
||||
col: 25,
|
||||
col: 21,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 119,
|
||||
Location {
|
||||
offset: 107,
|
||||
line: 3,
|
||||
col: 25,
|
||||
col: 21,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 121,
|
||||
Location {
|
||||
offset: 109,
|
||||
line: 3,
|
||||
col: 27,
|
||||
col: 23,
|
||||
},
|
||||
Field(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 121,
|
||||
Location {
|
||||
offset: 109,
|
||||
line: 3,
|
||||
col: 27,
|
||||
col: 23,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 121,
|
||||
Location {
|
||||
offset: 109,
|
||||
line: 3,
|
||||
col: 27,
|
||||
col: 23,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 121,
|
||||
Location {
|
||||
offset: 109,
|
||||
line: 3,
|
||||
col: 27,
|
||||
col: 23,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 121,
|
||||
Location {
|
||||
offset: 109,
|
||||
line: 3,
|
||||
col: 27,
|
||||
col: 23,
|
||||
},
|
||||
Ident(
|
||||
"args",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 125,
|
||||
Location {
|
||||
offset: 113,
|
||||
line: 3,
|
||||
col: 31,
|
||||
col: 27,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 127,
|
||||
Location {
|
||||
offset: 115,
|
||||
line: 3,
|
||||
col: 33,
|
||||
col: 29,
|
||||
},
|
||||
Ident(
|
||||
"stringvec",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 136,
|
||||
Location {
|
||||
offset: 124,
|
||||
line: 3,
|
||||
col: 42,
|
||||
col: 38,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 136,
|
||||
Location {
|
||||
offset: 124,
|
||||
line: 3,
|
||||
col: 42,
|
||||
col: 38,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 136,
|
||||
Location {
|
||||
offset: 124,
|
||||
line: 3,
|
||||
col: 42,
|
||||
col: 38,
|
||||
},
|
||||
),
|
||||
],
|
||||
ret: None,
|
||||
effects: [],
|
||||
},
|
||||
Coord {
|
||||
offset: 140,
|
||||
Location {
|
||||
offset: 128,
|
||||
line: 3,
|
||||
col: 46,
|
||||
col: 42,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 146,
|
||||
Location {
|
||||
offset: 130,
|
||||
line: 4,
|
||||
col: 5,
|
||||
col: 1,
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,50 +5,62 @@ expression: "format!(\"{:#?}\", t.unwrap())"
|
|||
Module(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
FnDef(
|
||||
FnDef(
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Fn,
|
||||
Coord {
|
||||
offset: 2,
|
||||
line: 0,
|
||||
col: 2,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Fn,
|
||||
Location {
|
||||
offset: 2,
|
||||
line: 0,
|
||||
col: 2,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
),
|
||||
),
|
||||
Location {
|
||||
offset: 2,
|
||||
line: 0,
|
||||
col: 2,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 3,
|
||||
line: 0,
|
||||
col: 3,
|
||||
},
|
||||
Prototype {
|
||||
name: Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 3,
|
||||
line: 0,
|
||||
col: 3,
|
||||
|
@ -57,7 +69,7 @@ Module(
|
|||
"some",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 7,
|
||||
line: 0,
|
||||
col: 7,
|
||||
|
@ -67,7 +79,7 @@ Module(
|
|||
ret: None,
|
||||
effects: [],
|
||||
},
|
||||
Coord {
|
||||
Location {
|
||||
offset: 11,
|
||||
line: 0,
|
||||
col: 11,
|
||||
|
@ -76,7 +88,7 @@ Module(
|
|||
Block(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 13,
|
||||
line: 0,
|
||||
col: 13,
|
||||
|
@ -84,7 +96,7 @@ Module(
|
|||
Binding(
|
||||
Binding(
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 17,
|
||||
line: 0,
|
||||
col: 17,
|
||||
|
@ -93,14 +105,14 @@ Module(
|
|||
"a",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 18,
|
||||
line: 0,
|
||||
col: 18,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 21,
|
||||
line: 0,
|
||||
col: 21,
|
||||
|
@ -108,7 +120,7 @@ Module(
|
|||
FnCall(
|
||||
FnCall(
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 21,
|
||||
line: 0,
|
||||
col: 21,
|
||||
|
@ -117,7 +129,7 @@ Module(
|
|||
"some_fnExpr",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 32,
|
||||
line: 0,
|
||||
col: 32,
|
||||
|
@ -125,7 +137,7 @@ Module(
|
|||
),
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 33,
|
||||
line: 0,
|
||||
col: 33,
|
||||
|
@ -133,14 +145,14 @@ Module(
|
|||
Integer(
|
||||
1,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 34,
|
||||
line: 0,
|
||||
col: 34,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 36,
|
||||
line: 0,
|
||||
col: 36,
|
||||
|
@ -148,14 +160,14 @@ Module(
|
|||
String(
|
||||
"2",
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 39,
|
||||
line: 0,
|
||||
col: 39,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 41,
|
||||
line: 0,
|
||||
col: 41,
|
||||
|
@ -163,7 +175,7 @@ Module(
|
|||
Integer(
|
||||
3,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 42,
|
||||
line: 0,
|
||||
col: 42,
|
||||
|
@ -172,7 +184,7 @@ Module(
|
|||
],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 43,
|
||||
line: 0,
|
||||
col: 43,
|
||||
|
@ -180,7 +192,7 @@ Module(
|
|||
),
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 43,
|
||||
line: 0,
|
||||
col: 43,
|
||||
|
@ -188,10 +200,9 @@ Module(
|
|||
),
|
||||
],
|
||||
),
|
||||
[],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 44,
|
||||
line: 0,
|
||||
col: 44,
|
||||
|
|
|
@ -5,50 +5,62 @@ expression: "format!(\"{:#?}\", t.unwrap())"
|
|||
Module(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
FnDef(
|
||||
FnDef(
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Fn,
|
||||
Coord {
|
||||
offset: 2,
|
||||
line: 0,
|
||||
col: 2,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Fn,
|
||||
Location {
|
||||
offset: 2,
|
||||
line: 0,
|
||||
col: 2,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
),
|
||||
),
|
||||
Location {
|
||||
offset: 2,
|
||||
line: 0,
|
||||
col: 2,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 3,
|
||||
line: 0,
|
||||
col: 3,
|
||||
},
|
||||
Prototype {
|
||||
name: Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 3,
|
||||
line: 0,
|
||||
col: 3,
|
||||
|
@ -57,7 +69,7 @@ Module(
|
|||
"call",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 7,
|
||||
line: 0,
|
||||
col: 7,
|
||||
|
@ -65,34 +77,34 @@ Module(
|
|||
),
|
||||
args: [
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 8,
|
||||
line: 0,
|
||||
col: 8,
|
||||
},
|
||||
Field(
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 8,
|
||||
line: 0,
|
||||
col: 8,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 8,
|
||||
line: 0,
|
||||
col: 8,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
Location {
|
||||
offset: 8,
|
||||
line: 0,
|
||||
col: 8,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 8,
|
||||
line: 0,
|
||||
col: 8,
|
||||
|
@ -101,14 +113,14 @@ Module(
|
|||
"a",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 9,
|
||||
line: 0,
|
||||
col: 9,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 10,
|
||||
line: 0,
|
||||
col: 10,
|
||||
|
@ -117,55 +129,55 @@ Module(
|
|||
"b",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 11,
|
||||
line: 0,
|
||||
col: 11,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 11,
|
||||
line: 0,
|
||||
col: 11,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 11,
|
||||
line: 0,
|
||||
col: 11,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 13,
|
||||
line: 0,
|
||||
col: 13,
|
||||
},
|
||||
Field(
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 13,
|
||||
line: 0,
|
||||
col: 13,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 13,
|
||||
line: 0,
|
||||
col: 13,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
Location {
|
||||
offset: 13,
|
||||
line: 0,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 13,
|
||||
line: 0,
|
||||
col: 13,
|
||||
|
@ -174,14 +186,14 @@ Module(
|
|||
"b",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 14,
|
||||
line: 0,
|
||||
col: 14,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 15,
|
||||
line: 0,
|
||||
col: 15,
|
||||
|
@ -190,21 +202,21 @@ Module(
|
|||
"c",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 0,
|
||||
col: 16,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 0,
|
||||
col: 16,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 0,
|
||||
col: 16,
|
||||
|
@ -214,7 +226,7 @@ Module(
|
|||
ret: None,
|
||||
effects: [
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 19,
|
||||
line: 0,
|
||||
col: 19,
|
||||
|
@ -223,14 +235,14 @@ Module(
|
|||
"throws",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 25,
|
||||
line: 0,
|
||||
col: 25,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 27,
|
||||
line: 0,
|
||||
col: 27,
|
||||
|
@ -239,14 +251,14 @@ Module(
|
|||
"awaits",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 33,
|
||||
line: 0,
|
||||
col: 33,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 35,
|
||||
line: 0,
|
||||
col: 35,
|
||||
|
@ -255,7 +267,7 @@ Module(
|
|||
"execs",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 40,
|
||||
line: 0,
|
||||
col: 40,
|
||||
|
@ -263,7 +275,7 @@ Module(
|
|||
),
|
||||
],
|
||||
},
|
||||
Coord {
|
||||
Location {
|
||||
offset: 41,
|
||||
line: 0,
|
||||
col: 41,
|
||||
|
@ -272,214 +284,141 @@ Module(
|
|||
Block(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 52,
|
||||
Location {
|
||||
offset: 48,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
FnCall(
|
||||
FnCall(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 52,
|
||||
Location {
|
||||
offset: 48,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Ident(
|
||||
"call",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 56,
|
||||
Location {
|
||||
offset: 52,
|
||||
line: 1,
|
||||
col: 12,
|
||||
col: 8,
|
||||
},
|
||||
),
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 58,
|
||||
Location {
|
||||
offset: 54,
|
||||
line: 1,
|
||||
col: 14,
|
||||
col: 10,
|
||||
},
|
||||
BinaryExpression(
|
||||
BinaryOperation {
|
||||
lhs: Spanned(
|
||||
Coord {
|
||||
offset: 57,
|
||||
Location {
|
||||
offset: 53,
|
||||
line: 1,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
Integer(
|
||||
1,
|
||||
),
|
||||
Coord {
|
||||
offset: 58,
|
||||
Location {
|
||||
offset: 54,
|
||||
line: 1,
|
||||
col: 14,
|
||||
col: 10,
|
||||
},
|
||||
),
|
||||
op: Add,
|
||||
rhs: Spanned(
|
||||
Coord {
|
||||
offset: 59,
|
||||
Location {
|
||||
offset: 55,
|
||||
line: 1,
|
||||
col: 15,
|
||||
col: 11,
|
||||
},
|
||||
Integer(
|
||||
1,
|
||||
),
|
||||
Coord {
|
||||
offset: 60,
|
||||
Location {
|
||||
offset: 56,
|
||||
line: 1,
|
||||
col: 16,
|
||||
col: 12,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
Coord {
|
||||
offset: 59,
|
||||
Location {
|
||||
offset: 55,
|
||||
line: 1,
|
||||
col: 15,
|
||||
col: 11,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 61,
|
||||
Location {
|
||||
offset: 57,
|
||||
line: 1,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 70,
|
||||
Location {
|
||||
offset: 62,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Binding(
|
||||
Binding(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 74,
|
||||
Location {
|
||||
offset: 66,
|
||||
line: 2,
|
||||
col: 12,
|
||||
col: 8,
|
||||
},
|
||||
Ident(
|
||||
"a",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 75,
|
||||
Location {
|
||||
offset: 67,
|
||||
line: 2,
|
||||
col: 13,
|
||||
col: 9,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 78,
|
||||
Location {
|
||||
offset: 70,
|
||||
line: 2,
|
||||
col: 16,
|
||||
col: 12,
|
||||
},
|
||||
Integer(
|
||||
1,
|
||||
),
|
||||
Coord {
|
||||
offset: 79,
|
||||
Location {
|
||||
offset: 71,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 79,
|
||||
Location {
|
||||
offset: 71,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
[
|
||||
(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 91,
|
||||
line: 3,
|
||||
col: 11,
|
||||
},
|
||||
Ident(
|
||||
"throws",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 97,
|
||||
line: 3,
|
||||
col: 17,
|
||||
},
|
||||
),
|
||||
Block(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 108,
|
||||
line: 4,
|
||||
col: 8,
|
||||
},
|
||||
FnCall(
|
||||
FnCall(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 108,
|
||||
line: 4,
|
||||
col: 8,
|
||||
},
|
||||
Ident(
|
||||
"raise",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 113,
|
||||
line: 4,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 114,
|
||||
line: 4,
|
||||
col: 14,
|
||||
},
|
||||
Integer(
|
||||
1,
|
||||
),
|
||||
Coord {
|
||||
offset: 115,
|
||||
line: 4,
|
||||
col: 15,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 116,
|
||||
line: 4,
|
||||
col: 16,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 122,
|
||||
line: 5,
|
||||
col: 5,
|
||||
Location {
|
||||
offset: 73,
|
||||
line: 3,
|
||||
col: 1,
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
|
@ -5,43 +5,55 @@ expression: "format!(\"{:#?}\", t.unwrap())"
|
|||
Module(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
StructDef(
|
||||
StructDef(
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Struct,
|
||||
Coord {
|
||||
offset: 6,
|
||||
line: 0,
|
||||
col: 6,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
KeywordAndVisibility(
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Struct,
|
||||
Location {
|
||||
offset: 6,
|
||||
line: 0,
|
||||
col: 6,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
Private,
|
||||
Location {
|
||||
offset: 0,
|
||||
line: 0,
|
||||
col: 0,
|
||||
},
|
||||
),
|
||||
),
|
||||
Location {
|
||||
offset: 6,
|
||||
line: 0,
|
||||
col: 6,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
Location {
|
||||
offset: 7,
|
||||
line: 0,
|
||||
col: 7,
|
||||
|
@ -50,7 +62,7 @@ Module(
|
|||
"VM",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
Location {
|
||||
offset: 9,
|
||||
line: 0,
|
||||
col: 9,
|
||||
|
@ -59,131 +71,131 @@ Module(
|
|||
Block(
|
||||
[
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 20,
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 20,
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 20,
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 20,
|
||||
Location {
|
||||
offset: 16,
|
||||
line: 1,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Ident(
|
||||
"a",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 21,
|
||||
Location {
|
||||
offset: 17,
|
||||
line: 1,
|
||||
col: 9,
|
||||
col: 5,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 23,
|
||||
Location {
|
||||
offset: 19,
|
||||
line: 1,
|
||||
col: 11,
|
||||
col: 7,
|
||||
},
|
||||
Ident(
|
||||
"string",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 29,
|
||||
Location {
|
||||
offset: 25,
|
||||
line: 1,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 29,
|
||||
Location {
|
||||
offset: 25,
|
||||
line: 1,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 38,
|
||||
Location {
|
||||
offset: 30,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
FieldDef(
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 38,
|
||||
Location {
|
||||
offset: 30,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Private,
|
||||
Coord {
|
||||
offset: 38,
|
||||
Location {
|
||||
offset: 30,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 38,
|
||||
Location {
|
||||
offset: 30,
|
||||
line: 2,
|
||||
col: 8,
|
||||
col: 4,
|
||||
},
|
||||
Ident(
|
||||
"b",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 39,
|
||||
Location {
|
||||
offset: 31,
|
||||
line: 2,
|
||||
col: 9,
|
||||
col: 5,
|
||||
},
|
||||
),
|
||||
Spanned(
|
||||
Coord {
|
||||
offset: 41,
|
||||
Location {
|
||||
offset: 33,
|
||||
line: 2,
|
||||
col: 11,
|
||||
col: 7,
|
||||
},
|
||||
Ident(
|
||||
"string",
|
||||
None,
|
||||
),
|
||||
Coord {
|
||||
offset: 47,
|
||||
Location {
|
||||
offset: 39,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 47,
|
||||
Location {
|
||||
offset: 39,
|
||||
line: 2,
|
||||
col: 17,
|
||||
col: 13,
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Coord {
|
||||
offset: 53,
|
||||
Location {
|
||||
offset: 41,
|
||||
line: 3,
|
||||
col: 5,
|
||||
col: 1,
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{lexer::Location, Db};
|
||||
pub use crate::{lexer::Location, Db};
|
||||
use hashbrown::HashMap;
|
||||
use okstd::prelude::*;
|
||||
use std::{fmt::Display, ops::Range};
|
||||
|
@ -17,6 +17,17 @@ impl<T> Spanned<T> {
|
|||
}
|
||||
}
|
||||
|
||||
trait GetSelf<T> {
|
||||
fn into(self) -> T;
|
||||
}
|
||||
|
||||
impl<T> GetSelf<T> for Spanned<T> {
|
||||
fn into(self) -> T {
|
||||
self.1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T: Display> Display for Spanned<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.1)
|
||||
|
|
|
@ -145,8 +145,8 @@ Let: Spanned<Keyword> = <lo:@L> "let" <hi:@R> => span!(lo, Keyword::Let, hi);
|
|||
True: Node = "true" => Node::Bool(true);
|
||||
False: Node = "false" => Node::Bool(false);
|
||||
|
||||
KeywordAndVisibility<T>: KeywordAndVisibility = {
|
||||
<v:Visibility> <k:T> => KeywordAndVisibility(k, v),
|
||||
KeywordAndVisibility<T>: Spanned<KeywordAndVisibility> = {
|
||||
<lo:@L> <v:Visibility> <k:T> <hi:@R> => span!(lo, KeywordAndVisibility(k, v), hi),
|
||||
};
|
||||
|
||||
Ident: Spanned<Ident> = {
|
||||
|
@ -321,7 +321,7 @@ WhenBlock: (Spanned<Ident>,Block<Spanned<Node>>) = {
|
|||
};
|
||||
|
||||
FnDef: Spanned<Node> = {
|
||||
<l:@L> <kwv:KeywordAndVisibility<Fn>> <proto:Prototype> <block:Block<Statement>> <handlers:(WhenBlock)*> <r:@R> => span!(l, Node::FnDef(FnDef(kwv,proto, block, handlers)), r),
|
||||
<l:@L> <kwv:KeywordAndVisibility<Fn>> <proto:Prototype> <block:Block<Statement>> <r:@R> => span!(l, Node::FnDef(FnDef(kwv,proto, block)), r),
|
||||
};
|
||||
|
||||
EffectDef: Spanned<Node> = {
|
||||
|
|
22092
src/parser/src.rs
22092
src/parser/src.rs
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue