mirror of
https://github.com/nushell/nushell
synced 2024-12-29 14:33:13 +00:00
Start moving towards decls and add a simple eval
This commit is contained in:
parent
9916f35b22
commit
697bf16f26
7 changed files with 164 additions and 35 deletions
7
src/declaration.rs
Normal file
7
src/declaration.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
use crate::{BlockId, Signature};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Declaration {
|
||||||
|
pub signature: Signature,
|
||||||
|
pub body: Option<BlockId>,
|
||||||
|
}
|
95
src/eval.rs
Normal file
95
src/eval.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
use crate::{parser::Operator, Block, Expr, Expression, Span, Statement};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ShellError {
|
||||||
|
Mismatch(String, Span),
|
||||||
|
Unsupported(Span),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Engine;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Value {
|
||||||
|
Int { val: i64, span: Span },
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Value {
|
||||||
|
pub fn add(&self, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
|
match (self, rhs) {
|
||||||
|
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
||||||
|
val: lhs + rhs,
|
||||||
|
span: Span::unknown(),
|
||||||
|
}),
|
||||||
|
_ => Ok(Value::Unknown),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Engine {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Engine {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval_operator(&self, op: &Expression) -> Result<Operator, ShellError> {
|
||||||
|
match op {
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Operator(operator),
|
||||||
|
..
|
||||||
|
} => Ok(operator.clone()),
|
||||||
|
Expression { span, .. } => Err(ShellError::Mismatch("operator".to_string(), *span)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval_expression(&self, expr: &Expression) -> Result<Value, ShellError> {
|
||||||
|
match expr.expr {
|
||||||
|
Expr::Int(i) => Ok(Value::Int {
|
||||||
|
val: i,
|
||||||
|
span: expr.span,
|
||||||
|
}),
|
||||||
|
Expr::Var(v) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Call(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::ExternalCall(_, _) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Operator(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::BinaryOp(_, _, _) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Subexpression(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Block(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::List(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Table(_, _) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Literal(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::String(_) => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
Expr::Garbage => Err(ShellError::Unsupported(expr.span)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval_block(&self, block: &Block) -> Result<Value, ShellError> {
|
||||||
|
let mut last = Ok(Value::Unknown);
|
||||||
|
|
||||||
|
for stmt in &block.stmts {
|
||||||
|
match stmt {
|
||||||
|
Statement::Expression(expression) => match &expression.expr {
|
||||||
|
Expr::BinaryOp(lhs, op, rhs) => {
|
||||||
|
let lhs = self.eval_expression(&lhs)?;
|
||||||
|
let op = self.eval_operator(&op)?;
|
||||||
|
let rhs = self.eval_expression(&rhs)?;
|
||||||
|
|
||||||
|
match op {
|
||||||
|
Operator::Plus => last = lhs.add(&rhs),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
last
|
||||||
|
}
|
||||||
|
}
|
10
src/lib.rs
10
src/lib.rs
|
@ -1,3 +1,5 @@
|
||||||
|
mod declaration;
|
||||||
|
mod eval;
|
||||||
mod lex;
|
mod lex;
|
||||||
mod lite_parse;
|
mod lite_parse;
|
||||||
mod parse_error;
|
mod parse_error;
|
||||||
|
@ -6,10 +8,14 @@ mod parser_state;
|
||||||
mod signature;
|
mod signature;
|
||||||
mod span;
|
mod span;
|
||||||
|
|
||||||
|
pub use declaration::Declaration;
|
||||||
|
pub use eval::Engine;
|
||||||
pub use lex::{lex, LexMode, Token, TokenContents};
|
pub use lex::{lex, LexMode, Token, TokenContents};
|
||||||
pub use lite_parse::{lite_parse, LiteBlock, LiteCommand, LiteStatement};
|
pub use lite_parse::{lite_parse, LiteBlock, LiteCommand, LiteStatement};
|
||||||
pub use parse_error::ParseError;
|
pub use parse_error::ParseError;
|
||||||
pub use parser::{Call, Expr, Expression, Import, Pipeline, Statement, SyntaxShape, VarDecl};
|
pub use parser::{
|
||||||
pub use parser_state::{DeclId, ParserState, ParserWorkingSet, VarId};
|
Block, Call, Expr, Expression, Import, Pipeline, Statement, SyntaxShape, VarDecl,
|
||||||
|
};
|
||||||
|
pub use parser_state::{BlockId, DeclId, ParserState, ParserWorkingSet, VarId};
|
||||||
pub use signature::Signature;
|
pub use signature::Signature;
|
||||||
pub use span::Span;
|
pub use span::Span;
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -1,20 +1,20 @@
|
||||||
use engine_q::{ParserWorkingSet, Signature, SyntaxShape};
|
use engine_q::{Engine, ParserWorkingSet, Signature, SyntaxShape};
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
if let Some(path) = std::env::args().nth(1) {
|
if let Some(path) = std::env::args().nth(1) {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
|
|
||||||
let sig = Signature::build("bar")
|
let sig = Signature::build("bar")
|
||||||
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
|
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
|
||||||
.switch("--rock", "rock!!", Some('r'));
|
.switch("--rock", "rock!!", Some('r'));
|
||||||
working_set.add_decl((b"bar").to_vec(), sig);
|
working_set.add_decl((b"bar").to_vec(), sig.into());
|
||||||
|
|
||||||
let sig =
|
let sig =
|
||||||
Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition");
|
Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition");
|
||||||
working_set.add_decl((b"where").to_vec(), sig);
|
working_set.add_decl((b"where").to_vec(), sig.into());
|
||||||
|
|
||||||
let sig = Signature::build("if")
|
let sig = Signature::build("if")
|
||||||
.required("cond", SyntaxShape::RowCondition, "condition")
|
.required("cond", SyntaxShape::RowCondition, "condition")
|
||||||
|
@ -25,7 +25,7 @@ fn main() -> std::io::Result<()> {
|
||||||
"else keyword",
|
"else keyword",
|
||||||
)
|
)
|
||||||
.required("else_block", SyntaxShape::Block, "else block");
|
.required("else_block", SyntaxShape::Block, "else block");
|
||||||
working_set.add_decl((b"if").to_vec(), sig);
|
working_set.add_decl((b"if").to_vec(), sig.into());
|
||||||
|
|
||||||
let sig = Signature::build("let")
|
let sig = Signature::build("let")
|
||||||
.required("var_name", SyntaxShape::Variable, "variable name")
|
.required("var_name", SyntaxShape::Variable, "variable name")
|
||||||
|
@ -35,7 +35,7 @@ fn main() -> std::io::Result<()> {
|
||||||
SyntaxShape::Expression,
|
SyntaxShape::Expression,
|
||||||
"the value to set the variable to",
|
"the value to set the variable to",
|
||||||
);
|
);
|
||||||
working_set.add_decl((b"let").to_vec(), sig);
|
working_set.add_decl((b"let").to_vec(), sig.into());
|
||||||
|
|
||||||
let sig = Signature::build("alias")
|
let sig = Signature::build("alias")
|
||||||
.required("var_name", SyntaxShape::Variable, "variable name")
|
.required("var_name", SyntaxShape::Variable, "variable name")
|
||||||
|
@ -45,14 +45,14 @@ fn main() -> std::io::Result<()> {
|
||||||
SyntaxShape::Expression,
|
SyntaxShape::Expression,
|
||||||
"the value to set the variable to",
|
"the value to set the variable to",
|
||||||
);
|
);
|
||||||
working_set.add_decl((b"alias").to_vec(), sig);
|
working_set.add_decl((b"alias").to_vec(), sig.into());
|
||||||
|
|
||||||
let sig = Signature::build("sum").required(
|
let sig = Signature::build("sum").required(
|
||||||
"arg",
|
"arg",
|
||||||
SyntaxShape::List(Box::new(SyntaxShape::Number)),
|
SyntaxShape::List(Box::new(SyntaxShape::Number)),
|
||||||
"list of numbers",
|
"list of numbers",
|
||||||
);
|
);
|
||||||
working_set.add_decl((b"sum").to_vec(), sig);
|
working_set.add_decl((b"sum").to_vec(), sig.into());
|
||||||
|
|
||||||
//let file = std::fs::read(&path)?;
|
//let file = std::fs::read(&path)?;
|
||||||
//let (output, err) = working_set.parse_file(&path, file);
|
//let (output, err) = working_set.parse_file(&path, file);
|
||||||
|
@ -61,6 +61,10 @@ fn main() -> std::io::Result<()> {
|
||||||
println!("error: {:?}", err);
|
println!("error: {:?}", err);
|
||||||
// println!("{}", size_of::<Statement>());
|
// println!("{}", size_of::<Statement>());
|
||||||
|
|
||||||
|
let engine = Engine::new();
|
||||||
|
let result = engine.eval_block(&output);
|
||||||
|
println!("{:?}", result);
|
||||||
|
|
||||||
// let mut buffer = String::new();
|
// let mut buffer = String::new();
|
||||||
// let stdin = std::io::stdin();
|
// let stdin = std::io::stdin();
|
||||||
// let mut handle = stdin.lock();
|
// let mut handle = stdin.lock();
|
||||||
|
|
|
@ -137,8 +137,8 @@ pub enum Expr {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Expression {
|
pub struct Expression {
|
||||||
expr: Expr,
|
pub expr: Expr,
|
||||||
span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn garbage(span: Span) -> Expression {
|
pub fn garbage(span: Span) -> Expression {
|
||||||
|
@ -504,7 +504,7 @@ impl ParserWorkingSet {
|
||||||
let mut call = Call::new();
|
let mut call = Call::new();
|
||||||
call.decl_id = decl_id;
|
call.decl_id = decl_id;
|
||||||
|
|
||||||
let sig = self
|
let decl = self
|
||||||
.get_decl(decl_id)
|
.get_decl(decl_id)
|
||||||
.expect("internal error: bad DeclId")
|
.expect("internal error: bad DeclId")
|
||||||
.clone();
|
.clone();
|
||||||
|
@ -520,7 +520,8 @@ impl ParserWorkingSet {
|
||||||
let arg_span = spans[spans_idx];
|
let arg_span = spans[spans_idx];
|
||||||
|
|
||||||
// Check if we're on a long flag, if so, parse
|
// Check if we're on a long flag, if so, parse
|
||||||
let (long_name, arg, err) = self.parse_long_flag(spans, &mut spans_idx, &sig);
|
let (long_name, arg, err) =
|
||||||
|
self.parse_long_flag(spans, &mut spans_idx, &decl.signature);
|
||||||
if let Some(long_name) = long_name {
|
if let Some(long_name) = long_name {
|
||||||
// We found a long flag, like --bar
|
// We found a long flag, like --bar
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
@ -531,7 +532,7 @@ impl ParserWorkingSet {
|
||||||
|
|
||||||
// Check if we're on a short flag or group of short flags, if so, parse
|
// Check if we're on a short flag or group of short flags, if so, parse
|
||||||
let (short_flags, err) =
|
let (short_flags, err) =
|
||||||
self.parse_short_flags(spans, &mut spans_idx, positional_idx, &sig);
|
self.parse_short_flags(spans, &mut spans_idx, positional_idx, &decl.signature);
|
||||||
|
|
||||||
if let Some(short_flags) = short_flags {
|
if let Some(short_flags) = short_flags {
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
@ -555,9 +556,9 @@ impl ParserWorkingSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a positional arg if there is one
|
// Parse a positional arg if there is one
|
||||||
if let Some(positional) = sig.get_positional(positional_idx) {
|
if let Some(positional) = decl.signature.get_positional(positional_idx) {
|
||||||
//Make sure we leave enough spans for the remaining positionals
|
//Make sure we leave enough spans for the remaining positionals
|
||||||
let remainder = sig.num_positionals() - positional_idx;
|
let remainder = decl.signature.num_positionals() - positional_idx;
|
||||||
|
|
||||||
let (arg, err) = self.parse_multispan_value(
|
let (arg, err) = self.parse_multispan_value(
|
||||||
&spans[..(spans.len() - remainder + 1)],
|
&spans[..(spans.len() - remainder + 1)],
|
||||||
|
@ -575,7 +576,7 @@ impl ParserWorkingSet {
|
||||||
spans_idx += 1;
|
spans_idx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let err = check_call(spans[0], &sig, &call);
|
let err = check_call(spans[0], &decl.signature, &call);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
// FIXME: type unknown
|
// FIXME: type unknown
|
||||||
|
@ -1185,6 +1186,7 @@ impl ParserWorkingSet {
|
||||||
expr_stack.push(lhs);
|
expr_stack.push(lhs);
|
||||||
|
|
||||||
while idx < spans.len() {
|
while idx < spans.len() {
|
||||||
|
println!("idx: {}", idx);
|
||||||
let (op, err) = self.parse_operator(spans[idx]);
|
let (op, err) = self.parse_operator(spans[idx]);
|
||||||
error = error.or(err);
|
error = error.or(err);
|
||||||
|
|
||||||
|
@ -1417,7 +1419,7 @@ mod tests {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
|
|
||||||
let (block, err) = working_set.parse_source(b"foo");
|
let (block, err) = working_set.parse_source(b"foo");
|
||||||
|
|
||||||
|
@ -1440,7 +1442,7 @@ mod tests {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
|
|
||||||
let (_, err) = working_set.parse_source(b"foo --jazz");
|
let (_, err) = working_set.parse_source(b"foo --jazz");
|
||||||
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
||||||
|
@ -1451,7 +1453,7 @@ mod tests {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
|
|
||||||
let (_, err) = working_set.parse_source(b"foo -j");
|
let (_, err) = working_set.parse_source(b"foo -j");
|
||||||
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
||||||
|
@ -1464,7 +1466,7 @@ mod tests {
|
||||||
let sig = Signature::build("foo")
|
let sig = Signature::build("foo")
|
||||||
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
|
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
|
||||||
.named("--math", SyntaxShape::Int, "math!!", Some('m'));
|
.named("--math", SyntaxShape::Int, "math!!", Some('m'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
let (_, err) = working_set.parse_source(b"foo -mj");
|
let (_, err) = working_set.parse_source(b"foo -mj");
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
err,
|
err,
|
||||||
|
@ -1477,7 +1479,7 @@ mod tests {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
let (_, err) = working_set.parse_source(b"foo -mj");
|
let (_, err) = working_set.parse_source(b"foo -mj");
|
||||||
assert!(matches!(err, Some(ParseError::UnknownFlag(..))));
|
assert!(matches!(err, Some(ParseError::UnknownFlag(..))));
|
||||||
}
|
}
|
||||||
|
@ -1487,7 +1489,7 @@ mod tests {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
let (_, err) = working_set.parse_source(b"foo -j 100");
|
let (_, err) = working_set.parse_source(b"foo -j 100");
|
||||||
assert!(matches!(err, Some(ParseError::ExtraPositional(..))));
|
assert!(matches!(err, Some(ParseError::ExtraPositional(..))));
|
||||||
}
|
}
|
||||||
|
@ -1497,7 +1499,7 @@ mod tests {
|
||||||
let mut working_set = ParserWorkingSet::new(None);
|
let mut working_set = ParserWorkingSet::new(None);
|
||||||
|
|
||||||
let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!");
|
let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!");
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
let (_, err) = working_set.parse_source(b"foo");
|
let (_, err) = working_set.parse_source(b"foo");
|
||||||
assert!(matches!(err, Some(ParseError::MissingPositional(..))));
|
assert!(matches!(err, Some(ParseError::MissingPositional(..))));
|
||||||
}
|
}
|
||||||
|
@ -1508,7 +1510,7 @@ mod tests {
|
||||||
|
|
||||||
let sig =
|
let sig =
|
||||||
Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None);
|
Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None);
|
||||||
working_set.add_decl((b"foo").to_vec(), sig);
|
working_set.add_decl((b"foo").to_vec(), sig.into());
|
||||||
let (_, err) = working_set.parse_source(b"foo");
|
let (_, err) = working_set.parse_source(b"foo");
|
||||||
assert!(matches!(err, Some(ParseError::MissingRequiredFlag(..))));
|
assert!(matches!(err, Some(ParseError::MissingRequiredFlag(..))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use crate::{Signature, Span};
|
use crate::{parser::Block, Declaration, Signature, Span};
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
pub struct ParserState {
|
pub struct ParserState {
|
||||||
files: Vec<(String, usize, usize)>,
|
files: Vec<(String, usize, usize)>,
|
||||||
file_contents: Vec<u8>,
|
file_contents: Vec<u8>,
|
||||||
vars: Vec<Type>,
|
vars: Vec<Type>,
|
||||||
decls: Vec<Signature>,
|
decls: Vec<Declaration>,
|
||||||
|
blocks: Vec<Block>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
@ -16,6 +17,7 @@ pub enum Type {
|
||||||
|
|
||||||
pub type VarId = usize;
|
pub type VarId = usize;
|
||||||
pub type DeclId = usize;
|
pub type DeclId = usize;
|
||||||
|
pub type BlockId = usize;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ScopeFrame {
|
struct ScopeFrame {
|
||||||
|
@ -45,6 +47,7 @@ impl ParserState {
|
||||||
file_contents: vec![],
|
file_contents: vec![],
|
||||||
vars: vec![],
|
vars: vec![],
|
||||||
decls: vec![],
|
decls: vec![],
|
||||||
|
blocks: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +61,7 @@ impl ParserState {
|
||||||
this.file_contents.extend(working_set.file_contents);
|
this.file_contents.extend(working_set.file_contents);
|
||||||
this.decls.extend(working_set.decls);
|
this.decls.extend(working_set.decls);
|
||||||
this.vars.extend(working_set.vars);
|
this.vars.extend(working_set.vars);
|
||||||
|
this.blocks.extend(working_set.blocks);
|
||||||
|
|
||||||
//FIXME: add scope frame merging
|
//FIXME: add scope frame merging
|
||||||
} else {
|
} else {
|
||||||
|
@ -81,7 +85,7 @@ impl ParserState {
|
||||||
self.vars.get(var_id)
|
self.vars.get(var_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_decl(&self, decl_id: DeclId) -> Option<&Signature> {
|
pub fn get_decl(&self, decl_id: DeclId) -> Option<&Declaration> {
|
||||||
self.decls.get(decl_id)
|
self.decls.get(decl_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +111,8 @@ pub struct ParserWorkingSet {
|
||||||
files: Vec<(String, usize, usize)>,
|
files: Vec<(String, usize, usize)>,
|
||||||
pub(crate) file_contents: Vec<u8>,
|
pub(crate) file_contents: Vec<u8>,
|
||||||
vars: Vec<Type>, // indexed by VarId
|
vars: Vec<Type>, // indexed by VarId
|
||||||
decls: Vec<Signature>, // indexed by DeclId
|
decls: Vec<Declaration>, // indexed by DeclId
|
||||||
|
blocks: Vec<Block>, // indexed by BlockId
|
||||||
permanent_state: Option<Arc<ParserState>>,
|
permanent_state: Option<Arc<ParserState>>,
|
||||||
scope: Vec<ScopeFrame>,
|
scope: Vec<ScopeFrame>,
|
||||||
}
|
}
|
||||||
|
@ -119,6 +124,7 @@ impl ParserWorkingSet {
|
||||||
file_contents: vec![],
|
file_contents: vec![],
|
||||||
vars: vec![],
|
vars: vec![],
|
||||||
decls: vec![],
|
decls: vec![],
|
||||||
|
blocks: vec![],
|
||||||
permanent_state,
|
permanent_state,
|
||||||
scope: vec![ScopeFrame::new()],
|
scope: vec![ScopeFrame::new()],
|
||||||
}
|
}
|
||||||
|
@ -134,13 +140,13 @@ impl ParserWorkingSet {
|
||||||
self.files.len() + parent_len
|
self.files.len() + parent_len
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_decl(&mut self, name: Vec<u8>, sig: Signature) -> DeclId {
|
pub fn add_decl(&mut self, name: Vec<u8>, decl: Declaration) -> DeclId {
|
||||||
let scope_frame = self
|
let scope_frame = self
|
||||||
.scope
|
.scope
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.expect("internal error: missing required scope frame");
|
.expect("internal error: missing required scope frame");
|
||||||
|
|
||||||
self.decls.push(sig);
|
self.decls.push(decl);
|
||||||
let decl_id = self.decls.len() - 1;
|
let decl_id = self.decls.len() - 1;
|
||||||
|
|
||||||
scope_frame.decls.insert(name, decl_id);
|
scope_frame.decls.insert(name, decl_id);
|
||||||
|
@ -246,7 +252,7 @@ impl ParserWorkingSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_decl(&self, decl_id: DeclId) -> Option<&Signature> {
|
pub fn get_decl(&self, decl_id: DeclId) -> Option<&Declaration> {
|
||||||
if let Some(permanent_state) = &self.permanent_state {
|
if let Some(permanent_state) = &self.permanent_state {
|
||||||
let num_permanent_decls = permanent_state.num_decls();
|
let num_permanent_decls = permanent_state.num_decls();
|
||||||
if decl_id < num_permanent_decls {
|
if decl_id < num_permanent_decls {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::parser::SyntaxShape;
|
use crate::{parser::SyntaxShape, Declaration};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Flag {
|
pub struct Flag {
|
||||||
|
@ -216,3 +216,12 @@ impl Signature {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<Declaration> for Signature {
|
||||||
|
fn into(self) -> Declaration {
|
||||||
|
Declaration {
|
||||||
|
signature: self,
|
||||||
|
body: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue