Skip to content

Commit 71ad2ed

Browse files
committed
Initial commit
0 parents  commit 71ad2ed

27 files changed

+1175
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
**/*.rs.bk

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[package]
2+
name = "lexica"
3+
version = "0.1.0"
4+
authors = ["Techno-coder <[email protected]>"]
5+
edition = "2018"

rust-toolchain

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nightly

src/compiler/mod.rs

Whitespace-only changes.

src/display/indent_writer.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use std::fmt;
2+
3+
pub struct IndentWriter<'a, T> {
4+
inner: &'a mut T,
5+
on_new_line: bool,
6+
}
7+
8+
impl<'a, T> IndentWriter<'a, T> where T: fmt::Write {
9+
pub fn wrap(inner: &'a mut T) -> Self {
10+
Self { inner, on_new_line: true }
11+
}
12+
}
13+
14+
impl<'a, T> fmt::Write for IndentWriter<'a, T> where T: fmt::Write {
15+
fn write_str(&mut self, mut s: &str) -> Result<(), fmt::Error> {
16+
while !s.is_empty() {
17+
if self.on_new_line {
18+
self.inner.write_char('\t')?;
19+
}
20+
21+
let split = match s.find('\n') {
22+
Some(position) => {
23+
self.on_new_line = true;
24+
position + 1
25+
}
26+
None => {
27+
self.on_new_line = false;
28+
s.len()
29+
}
30+
};
31+
32+
self.inner.write_str(&s[..split])?;
33+
s = &s[split..];
34+
}
35+
Ok(())
36+
}
37+
}

src/display/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub use self::indent_writer::*;
2+
3+
mod indent_writer;
4+

src/interpreter/context.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use std::collections::HashMap;
2+
use std::marker::PhantomData;
3+
4+
use crate::node::Identifier;
5+
6+
use super::NodeConstruct;
7+
8+
#[derive(Debug, Default)]
9+
pub struct Context<'a> {
10+
bindings: HashMap<Identifier<'a>, i64>,
11+
evaluations: HashMap<EvaluationKey<'a>, i64>,
12+
}
13+
14+
impl<'a> Context<'a> {
15+
pub fn register_binding(&mut self, identifier: Identifier<'a>, value: i64) {
16+
self.bindings.insert(identifier, value);
17+
}
18+
19+
pub fn invalidate_binding(&mut self, identifier: &Identifier<'a>) {
20+
self.bindings.remove(identifier);
21+
}
22+
23+
pub fn binding_value(&self, identifier: &Identifier<'a>) -> &i64 {
24+
self.bindings.get(identifier)
25+
.expect(&format!("Binding does not exist for {:?}", identifier))
26+
}
27+
28+
pub fn cache_evaluation(&mut self, node: &'a NodeConstruct, value: i64) {
29+
self.evaluations.insert(EvaluationKey::resolve(node), value);
30+
}
31+
32+
pub fn invalidate_evaluation(&mut self, node: &'a NodeConstruct) {
33+
self.evaluations.remove(&EvaluationKey::resolve(node));
34+
}
35+
36+
pub fn has_evaluated(&self, node: &'a NodeConstruct) -> bool {
37+
self.evaluations.contains_key(&EvaluationKey::resolve(node))
38+
}
39+
40+
pub fn evaluation(&self, node: &'a NodeConstruct) -> &i64 {
41+
self.evaluations.get(&EvaluationKey::resolve(node))
42+
.expect(&format!("Evaluation does not exist for {:?}", node))
43+
}
44+
}
45+
46+
#[derive(Debug, Eq, PartialEq, Hash)]
47+
struct EvaluationKey<'a> {
48+
pointer: *const usize,
49+
lifetime: PhantomData<&'a NodeConstruct<'a>>,
50+
}
51+
52+
impl<'a> EvaluationKey<'a> {
53+
pub fn resolve(node: &'a NodeConstruct) -> Self {
54+
EvaluationKey {
55+
pointer: node as *const NodeConstruct as *const _,
56+
lifetime: PhantomData,
57+
}
58+
}
59+
}

src/interpreter/dependency_buffer.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use super::{Dependency, Direction};
2+
3+
#[derive(Debug)]
4+
pub struct DependencyBuffer<'a> {
5+
buffer: Vec<Dependency<'a>>,
6+
split_index: usize,
7+
direction: Direction,
8+
}
9+
10+
impl<'a> DependencyBuffer<'a> {
11+
pub fn new(buffer: Vec<Dependency<'a>>, direction: Direction) -> Self {
12+
let split_index = match direction {
13+
Direction::Advance => 0,
14+
Direction::Reverse => buffer.len() + 1,
15+
};
16+
Self { buffer, split_index, direction }
17+
}
18+
19+
/// Advances the cursor and returns the next node construct
20+
/// Cursor holds if changing direction
21+
pub fn advance(&mut self) -> Option<&Dependency<'a>> {
22+
match self.direction {
23+
Direction::Advance => self.split_index += 1,
24+
Direction::Reverse => self.direction = Direction::Advance
25+
}
26+
self.buffer.get(self.split_index - 1)
27+
}
28+
29+
/// Advances the cursor in reverse and returns the next node construct
30+
/// Cursor holds if changing direction
31+
pub fn reverse(&mut self) -> Option<&Dependency<'a>> {
32+
if self.direction == Direction::Advance {
33+
self.direction = Direction::Reverse;
34+
self.split_index += 1;
35+
}
36+
37+
if self.split_index > 1 {
38+
self.split_index -= 1;
39+
self.buffer.get(self.split_index - 1)
40+
} else {
41+
None
42+
}
43+
}
44+
}

src/interpreter/direction.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2+
pub enum Direction {
3+
Advance,
4+
Reverse,
5+
}
6+
7+
impl Direction {
8+
pub fn compose(&self, other: &Direction) -> Direction {
9+
if self == other {
10+
Direction::Advance
11+
} else {
12+
Direction::Reverse
13+
}
14+
}
15+
16+
pub fn invert(&self) -> Direction {
17+
match self {
18+
Direction::Advance => Direction::Reverse,
19+
Direction::Reverse => Direction::Advance,
20+
}
21+
}
22+
}

src/interpreter/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub enum InterpreterError {}

src/interpreter/mod.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
pub use self::context::*;
2+
pub use self::dependency_buffer::*;
3+
pub use self::direction::*;
4+
pub use self::error::*;
5+
pub use self::node_construct::*;
6+
pub use self::runtime::*;
7+
8+
mod context;
9+
mod node_construct;
10+
mod runtime;
11+
mod error;
12+
mod dependency_buffer;
13+
mod direction;
14+
15+
pub fn construct() -> crate::node::Function<'static> {
16+
use crate::node::*;
17+
Function {
18+
parameters: vec![
19+
Variable {
20+
identifier: Identifier("n"),
21+
data_type: Some(DataType(Identifier("u32"))),
22+
is_mutable: false,
23+
}
24+
],
25+
statements: vec![
26+
Statement::Binding(Binding {
27+
variable: Variable {
28+
identifier: Identifier("first"),
29+
data_type: None,
30+
is_mutable: true,
31+
},
32+
expression: Expression::LiteralInteger(1),
33+
}),
34+
Statement::Binding(Binding {
35+
variable: Variable {
36+
identifier: Identifier("second"),
37+
data_type: None,
38+
is_mutable: true,
39+
},
40+
expression: Expression::LiteralInteger(1),
41+
}),
42+
Statement::Binding(Binding {
43+
variable: Variable {
44+
identifier: Identifier("counter"),
45+
data_type: None,
46+
is_mutable: true,
47+
},
48+
expression: Expression::LiteralInteger(1),
49+
}),
50+
Statement::ConditionalLoop(ConditionalLoop {
51+
start_condition: Some(Expression::BinaryOperation(Box::new(BinaryOperation {
52+
left: Expression::Variable(Identifier("counter")),
53+
right: Expression::LiteralInteger(1),
54+
operator: BinaryOperator::Equal,
55+
}))),
56+
end_condition: Expression::BinaryOperation(Box::new(BinaryOperation {
57+
left: Expression::Variable(Identifier("counter")),
58+
right: Expression::Variable(Identifier("n")),
59+
operator: BinaryOperator::Equal,
60+
})),
61+
statements: vec![
62+
Statement::Binding(Binding {
63+
variable: Variable {
64+
identifier: Identifier("summation"),
65+
data_type: None,
66+
is_mutable: false,
67+
},
68+
expression: Expression::BinaryOperation(Box::new(BinaryOperation {
69+
left: Expression::Variable(Identifier("first")),
70+
right: Expression::Variable(Identifier("second")),
71+
operator: BinaryOperator::Plus,
72+
})),
73+
}),
74+
Statement::Swap(Swap {
75+
left: Identifier("first"),
76+
right: Identifier("second"),
77+
}),
78+
Statement::Swap(Swap {
79+
left: Identifier("second"),
80+
right: Identifier("summation"),
81+
}),
82+
Statement::ExplicitDrop(ExplicitDrop {
83+
identifier: Identifier("summation"),
84+
expression: Expression::BinaryOperation(Box::new(BinaryOperation {
85+
left: Expression::Variable(Identifier("second")),
86+
right: Expression::Variable(Identifier("first")),
87+
operator: BinaryOperator::Minus,
88+
})),
89+
}),
90+
Statement::Mutation(Mutation::AddAssign(
91+
Identifier("counter"),
92+
Expression::LiteralInteger(1),
93+
)),
94+
],
95+
}),
96+
Statement::ExplicitDrop(ExplicitDrop {
97+
identifier: Identifier("n"),
98+
expression: Expression::Variable(Identifier("counter")),
99+
}),
100+
],
101+
return_value: Expression::Variable(Identifier("second")),
102+
}
103+
}

src/interpreter/node_construct.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::fmt::{Debug, Display};
2+
3+
use super::{Context, Direction};
4+
5+
pub trait NodeConstruct<'a>: Debug + Display {
6+
/// Nodes that are to be evaluated before this node is executed
7+
/// These nodes are only evaluated in advance mode
8+
fn dependencies(&'a self, _context: &mut Context<'a>) -> Vec<Dependency<'a>> { Vec::new() }
9+
fn execute(&'a self, context: &mut Context<'a>) -> Result<ExecutionStep, ()>;
10+
11+
/// Nodes that are to be evaluated before this node is reversed starting from the last
12+
/// These nodes are only evaluated in reverse mode and the direction should be
13+
/// as if they were evaluated in advance mode
14+
fn reverse_dependencies(&'a self, _context: &mut Context<'a>) -> Vec<Dependency<'a>> { Vec::new() }
15+
fn reverse(&'a self, context: &mut Context<'a>) -> Result<ExecutionStep, ()>;
16+
}
17+
18+
#[derive(Debug, Clone)]
19+
pub struct Dependency<'a> {
20+
pub node: &'a NodeConstruct<'a>,
21+
pub direction: Direction,
22+
}
23+
24+
impl<'a> Dependency<'a> {
25+
/// Specifies the node is to be executed by advancing
26+
pub fn advance(node: &'a NodeConstruct<'a>) -> Self {
27+
Self { node, direction: Direction::Advance }
28+
}
29+
30+
/// Specifies the node is to be executed in reverse
31+
pub fn reverse(node: &'a NodeConstruct<'a>) -> Self {
32+
Self { node, direction: Direction::Reverse }
33+
}
34+
}
35+
36+
#[derive(Debug)]
37+
pub enum ExecutionStep {
38+
Void,
39+
Repeat,
40+
Value(i64),
41+
}

0 commit comments

Comments
 (0)