Skip to content
Permalink
Browse files

Add spans to AST

  • Loading branch information...
kevinmehall committed Jan 14, 2018
1 parent d7931f4 commit cd2220ac4acbd8f8d68c8ee819a6358204194d89
@@ -16,6 +16,7 @@ byteorder = "1.0.0"
peg-syntax-ext = "0.5.0"
vec_map = "0.8.0"
scoped-pool = "1.0"
codemap = "0.1"

[dev-dependencies]
env_logger = "0.3"
@@ -48,8 +48,9 @@ fn main() {

for source_fname in imports {
let mut source = String::new();
fs::File::open(source_fname).unwrap().read_to_string(&mut source).unwrap();
loader.parse_module(&source).unwrap();
fs::File::open(&source_fname).unwrap().read_to_string(&mut source).unwrap();
let file = loader.codemap.borrow_mut().add_file(source_fname, source);
loader.parse_module(&file).unwrap();
}

let mut stack = signalspec::ProcessStack::new(&loader);
@@ -1,28 +1,29 @@
use super::eval::BinOp;
pub use data::Value;
pub use codemap::Spanned;

pub struct Module {
pub entries: Vec<ModuleEntry>,
pub entries: Vec<Spanned<ModuleEntry>>,
}

#[derive(Debug, Clone)]
pub struct Block {
pub lets: Vec<LetDef>,
pub actions: Vec<Action>,
pub lets: Vec<Spanned<LetDef>>,
pub actions: Vec<Spanned<Action>>,
}

#[derive(Debug, Clone)]
pub enum Action {
Repeat(Expr, Block),
Call(String, Expr, Option<Block>),
On(String, Expr, Option<Block>),
For(Vec<(String, Expr)>, Block),
Alt(Expr, Vec<AltArm>),
Repeat(Option<SpannedExpr>, Block),
Call(String, SpannedExpr, Option<Block>),
On(String, SpannedExpr, Option<Block>),
For(Vec<(String, SpannedExpr)>, Block),
Alt(SpannedExpr, Vec<AltArm>),
}

#[derive(Debug, Clone)]
pub struct AltArm {
pub discriminant: Expr,
pub discriminant: SpannedExpr,
pub block: Block,
}

@@ -36,61 +37,63 @@ pub enum ModuleEntry {

pub struct Def {
pub name: String,
pub param: Expr,
pub param: SpannedExpr,
pub top: Option<ProtocolRef>,
pub bottom: ProtocolRef,
pub block: Block,
}

pub struct PrimitiveHeader {
pub name: String,
pub param: Expr,
pub param: SpannedExpr,
pub top: Option<ProtocolRef>,
pub bottom: ProtocolRef,
}

pub struct Protocol {
pub name: String,
pub param: Expr,
pub param: SpannedExpr,
pub entries: Vec<ProtocolEntry>,
}

pub enum ProtocolEntry {
Message(String, Expr),
Message(String, SpannedExpr),
}

#[derive(Debug, Clone)]
pub struct ProtocolRef {
pub name: String,
pub param: Expr,
pub param: SpannedExpr,
}

#[derive(Debug, Clone)]
pub struct LetDef(pub String, pub Expr);
pub struct LetDef(pub String, pub SpannedExpr);

pub type SpannedExpr = Spanned<Expr>;

#[derive(Debug, Clone)]
pub enum Expr {
Value(Value),
String(String), // Produces an Item, not a Value, because it isn't fixed size
Func{ args: Box<Expr>, body: Box<Expr> }, // Produces an Item
Tup(Vec<Expr>),
Func{ args: Box<SpannedExpr>, body: Box<SpannedExpr> }, // Produces an Item
Tup(Vec<SpannedExpr>),
Ignore,

Union(Vec<Expr>),
Flip(Box<Expr>, Box<Expr>),
Range(Box<Expr>, Box<Expr>),
Choose(Box<Expr>, Vec<(Expr, Expr)>),
Concat(Vec<(Option<usize>, Expr)>),
Union(Vec<SpannedExpr>),
Flip(Option<Box<SpannedExpr>>, Option<Box<SpannedExpr>>),
Range(Box<SpannedExpr>, Box<SpannedExpr>),
Choose(Box<SpannedExpr>, Vec<(SpannedExpr, SpannedExpr)>),
Concat(Vec<(Option<usize>, SpannedExpr)>),

Bin(Box<Expr>, BinOp, Box<Expr>),
Bin(Box<SpannedExpr>, BinOp, Box<SpannedExpr>),

Call(Box<Expr>, Box<Expr>),
Call(Box<SpannedExpr>, Box<SpannedExpr>),
Var(String),
}

#[derive(Debug, Clone)]
pub enum Process {
Call(String, Expr),
Call(String, SpannedExpr),
Literal(ProcessLiteralDirection, ProtocolRef, Block),
Block(Block)
}
@@ -609,8 +609,9 @@ fn exprs() {
ctxt.add_primitive_fn("complex", fn_complex);
let scope = ctxt.prelude.borrow().child();

let expr = |e| {
let ast = grammar::valexpr(e).unwrap();
let expr = |e: &str| {
let file = ctxt.codemap.borrow_mut().add_file("<expr>".into(), e.into());
let ast = grammar::valexpr(&file.source(), file.span).unwrap();
super::expr::value(&ctxt, &scope, &ast)
};

@@ -11,11 +11,10 @@ fn resolve(ctx: &Ctxt, scope: Option<&Scope>, var_handler: &mut FnMut(&str) -> E
ast::Expr::Ignore => Expr::Ignored,
ast::Expr::Value(ref val) => Expr::Const(val.clone()),

ast::Expr::Flip(box ref down, box ref up) => {
debug!("Flip: {:?} {:?}", down, up);
ast::Expr::Flip(ref down, ref up) => {
Expr::Flip(
box resolve(ctx, scope, var_handler, down),
box resolve(ctx, scope, var_handler, up),
box resolve(ctx, scope, var_handler, down.as_ref().map_or(&ast::Expr::Ignore, |s| &s.node)),
box resolve(ctx, scope, var_handler, up.as_ref().map_or(&ast::Expr::Ignore, |s| &s.node)),
)
}

@@ -117,8 +116,8 @@ pub fn rexpr<'s>(ctxt: &'s Ctxt<'s>, scope: &Scope, e: &ast::Expr) -> Item {

ast::Expr::Func{ ref body, ref args } => {
Item::Func(ctxt.create_function(FunctionDef::Code(Func{
args: (**args).clone(),
body: (**body).clone(),
args: args.node.clone(),
body: body.node.clone(),
scope: scope.clone(),
})))
}
@@ -1,4 +1,5 @@
use std::cell::RefCell;
use codemap::{ CodeMap, File };

use super::{ ast, grammar, Item, PrimitiveDef };
use super::scope::Scope;
@@ -15,6 +16,7 @@ pub struct Ctxt<'a> {
pub protocol_scope: RefCell<ProtocolScope>, // TODO: should be scoped
pub protocols: Index<ProtocolDef, ProtocolId>,
pub functions: Index<FunctionDef, FunctionId>,
pub codemap: RefCell<CodeMap>,
}

pub struct Module {
@@ -35,6 +37,7 @@ impl<'a> Ctxt<'a> {
protocol_scope: RefCell::new(ProtocolScope::new()),
protocols: Index::new(),
functions: Index::new(),
codemap: RefCell::new(CodeMap::new()),
}
}

@@ -44,12 +47,14 @@ impl<'a> Ctxt<'a> {
}

pub fn define_primitive(&self, header_src: &str, implementations: Vec<PrimitiveDef>) {
let header = grammar::primitive_header(header_src).expect("failed to parse primitive header");
let file = self.codemap.borrow_mut().add_file("<primitive>".into(), header_src.into());
let header = grammar::primitive_header(&file.source(), file.span).expect("failed to parse primitive header");
self.protocol_scope.borrow_mut().add_primitive(self, &*self.prelude.borrow(), header, implementations);
}

pub fn define_prelude(&self, source: &str) {
let module = self.parse_module(source).expect("failed to parse prelude module");
let file = self.codemap.borrow_mut().add_file("<prelude>".into(), source.into());
let module = self.parse_module(&file).expect("failed to parse prelude module");
*self.prelude.borrow_mut() = module.scope;
}

@@ -64,20 +69,21 @@ impl<'a> Ctxt<'a> {
}

pub fn parse_process(&self, source: &str, shape_below: &Shape, fields_below: &Fields) -> Result<ProcessInfo, grammar::ParseError> {
let ast = try!(grammar::process(source));
let file = self.codemap.borrow_mut().add_file("<process>".into(), source.into());
let ast = try!(grammar::process(&file.source(), file.span));
Ok(super::program::resolve_process(self, &*self.prelude.borrow(), &*self.protocol_scope.borrow(), shape_below, fields_below, &ast))
}

pub fn parse_module(&self, source: &str) -> Result<Module, grammar::ParseError> {
let ast = grammar::module(source)?;
pub fn parse_module(&self, file: &File) -> Result<Module, grammar::ParseError> {
let ast = grammar::module(&file.source(), file.span)?;

let mut scope = self.prelude.borrow().child();
let mut with_blocks = vec![];
let mut protocols = vec![];
let mut tests = vec![];

for entry in ast.entries {
match entry {
match entry.node {
ast::ModuleEntry::Let(letdef) => {
super::step::resolve_letdef(self, &mut scope, &letdef);
}
@@ -53,7 +53,7 @@ pub fn resolve_protocol_invoke(ctx: &Ctxt, scope: &Scope, ast: &ast::ProtocolRef

fn resolve_protocol_match(_ctx: &Ctxt, scope: &Scope, ast: ast::ProtocolRef) -> ProtocolMatch {
if let Some(Item::Protocol(protocol_id)) = scope.get(&ast.name[..]) {
ProtocolMatch { id: protocol_id, param: ast.param }
ProtocolMatch { id: protocol_id, param: ast.param.node }
} else {
panic!("Protocol `{}` not found", ast.name);
}
@@ -88,7 +88,7 @@ impl ProtocolScope {
protocol: resolve_protocol_match(ctx, &scope, def.bottom),
name: def.name.clone(),
scope: scope,
param: def.param,
param: def.param.node,
shape_up: def.top,
implementation: DefImpl::Code(def.block)
});
@@ -99,7 +99,7 @@ impl ProtocolScope {
protocol: resolve_protocol_match(ctx, scope, header.bottom),
name: header.name.clone(),
scope: scope.child(),
param: header.param,
param: header.param.node,
shape_up: header.top,
implementation: DefImpl::Primitive(defs),
});
Oops, something went wrong.

0 comments on commit cd2220a

Please sign in to comment.
You can’t perform that action at this time.