cl-interpret: process use items and imports in the interpreter
This commit is contained in:
parent
af9c293907
commit
edabbe1655
@ -81,7 +81,6 @@ pub struct Item {
|
|||||||
/// What kind of [Item] is this?
|
/// What kind of [Item] is this?
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum ItemKind {
|
pub enum ItemKind {
|
||||||
// TODO: Import declaration ("use") item
|
|
||||||
// TODO: Trait declaration ("trait") item?
|
// TODO: Trait declaration ("trait") item?
|
||||||
/// A [module](Module)
|
/// A [module](Module)
|
||||||
Module(Module),
|
Module(Module),
|
||||||
|
@ -97,8 +97,8 @@ impl Environment {
|
|||||||
self.frames.push((frame, name));
|
self.frames.push((frame, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_frame(&mut self) -> Option<StackFrame> {
|
pub fn pop_frame(&mut self) -> Option<(StackFrame, &'static str)> {
|
||||||
self.frames.pop().map(|f| f.0)
|
self.frames.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval(&mut self, node: &impl Interpret) -> IResult<ConValue> {
|
pub fn eval(&mut self, node: &impl Interpret) -> IResult<ConValue> {
|
||||||
|
@ -68,7 +68,7 @@ impl Callable for Function {
|
|||||||
}
|
}
|
||||||
let res = body.interpret(&mut frame);
|
let res = body.interpret(&mut frame);
|
||||||
drop(frame);
|
drop(frame);
|
||||||
if let Some(upvars) = env.pop_frame() {
|
if let Some((upvars, _)) = env.pop_frame() {
|
||||||
self.upvars.replace(upvars);
|
self.upvars.replace(upvars);
|
||||||
}
|
}
|
||||||
match res {
|
match res {
|
||||||
|
@ -37,10 +37,7 @@ impl Interpret for Item {
|
|||||||
ItemKind::Struct(item) => item.interpret(env),
|
ItemKind::Struct(item) => item.interpret(env),
|
||||||
ItemKind::Enum(item) => item.interpret(env),
|
ItemKind::Enum(item) => item.interpret(env),
|
||||||
ItemKind::Impl(item) => item.interpret(env),
|
ItemKind::Impl(item) => item.interpret(env),
|
||||||
ItemKind::Use(item) => {
|
ItemKind::Use(item) => item.interpret(env),
|
||||||
eprintln!("TODO: namespaces and imports in the interpreter!\n{item}\n");
|
|
||||||
Ok(ConValue::Empty)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +77,7 @@ impl Interpret for Module {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let frame = env
|
let (frame, _) = env
|
||||||
.pop_frame()
|
.pop_frame()
|
||||||
.expect("Environment frames must be balanced");
|
.expect("Environment frames must be balanced");
|
||||||
env.insert(*name, Some(ConValue::Module(frame.into())));
|
env.insert(*name, Some(ConValue::Module(frame.into())));
|
||||||
@ -114,6 +111,73 @@ impl Interpret for Impl {
|
|||||||
body.interpret(env)
|
body.interpret(env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Interpret for Use {
|
||||||
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
|
let Self { absolute: _, tree } = self;
|
||||||
|
tree.interpret(env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Interpret for UseTree {
|
||||||
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
|
type Bindings = HashMap<Sym, ConValue>;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
fn get_bindings(
|
||||||
|
tree: &UseTree,
|
||||||
|
env: &mut Environment,
|
||||||
|
bindings: &mut Bindings,
|
||||||
|
) -> IResult<()> {
|
||||||
|
match tree {
|
||||||
|
UseTree::Tree(use_trees) => {
|
||||||
|
for tree in use_trees {
|
||||||
|
get_bindings(tree, env, bindings)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UseTree::Path(PathPart::Ident(name), tree) => {
|
||||||
|
let Ok(ConValue::Module(m)) = env.get(*name) else {
|
||||||
|
Err(Error::TypeError)?
|
||||||
|
};
|
||||||
|
env.push_frame(Interned::to_ref(name), *m);
|
||||||
|
let out = get_bindings(tree, env, bindings);
|
||||||
|
env.pop_frame();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
UseTree::Alias(name, alias) => {
|
||||||
|
bindings.insert(*alias, env.get(*name)?);
|
||||||
|
}
|
||||||
|
UseTree::Name(name) => {
|
||||||
|
bindings.insert(*name, env.get(*name)?);
|
||||||
|
}
|
||||||
|
UseTree::Glob => {
|
||||||
|
if let Some((frame, name)) = env.pop_frame() {
|
||||||
|
for (k, v) in &frame {
|
||||||
|
if let Some(v) = v {
|
||||||
|
bindings.insert(*k, v.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env.push_frame(name, frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
eprintln!("ERROR: Cannot use {other}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut bindings = Bindings::new();
|
||||||
|
get_bindings(self, env, &mut bindings)?;
|
||||||
|
|
||||||
|
for (name, value) in bindings {
|
||||||
|
env.insert(name, Some(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ConValue::Empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Interpret for Stmt {
|
impl Interpret for Stmt {
|
||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
let Self { extents: _, kind, semi } = self;
|
let Self { extents: _, kind, semi } = self;
|
||||||
|
@ -681,7 +681,11 @@ impl Parse<'_> for UseTree {
|
|||||||
let PathPart::Ident(name) = name else {
|
let PathPart::Ident(name) = name else {
|
||||||
Err(p.error(ErrorKind::ExpectedParsing { want: Parsing::Identifier }, P))?
|
Err(p.error(ErrorKind::ExpectedParsing { want: Parsing::Identifier }, P))?
|
||||||
};
|
};
|
||||||
UseTree::Name(name)
|
if p.match_type(TokenKind::As, P).is_ok() {
|
||||||
|
UseTree::Alias(name, p.parse()?)
|
||||||
|
} else {
|
||||||
|
UseTree::Name(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t => Err(p.error(Unexpected(t), Parsing::UseTree))?,
|
t => Err(p.error(Unexpected(t), Parsing::UseTree))?,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Formats numbers in hexadecimal, octal, or binary
|
//! Formats numbers in hexadecimal, octal, or binary
|
||||||
mod math;
|
mod math;
|
||||||
|
use math::{min, count_leading_zeroes};
|
||||||
|
|
||||||
fn as_digit(n: u32) -> char {
|
fn as_digit(n: u32) -> char {
|
||||||
(if n > 9 {
|
(if n > 9 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user