Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,3 @@ jobs:
with:
reporter: 'github-pr-check'
github_token: ${{ secrets.GITHUB_TOKEN }}

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ target/
*.pdb


reports/
reports/
30 changes: 30 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: local
hooks:
- id: cargo-fmt
name: cargo fmt
entry: cargo fmt -- --check
language: system
files: \.rs$
args: []
- id: lint
name: lint
entry: just lint
language: system
pass_filenames: false
files: \.rs$
args: []
- id: test
name: test
entry: just test
language: system
pass_filenames: false
files: \.rs$
args: []
stages: [pre-push]
18 changes: 18 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
https://craftinginterpreters.com/functions.html#function-objects

Implementing custom functions.

i.e
```lox
fun sayHi(first, last) {
print "Hi, " + first + " " + last + "!";
}
sayHi("Dear", "Reader");
```

The parsing for the func definition and the func call are implemented.

Work to do:
- Store the `IDENTIFIER:sayHi -> code to run` in interpreter
- Lookup this code
- Run this code
6 changes: 5 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ lint:
@cargo clippy --version
cargo clippy -- -D warnings -W clippy::pedantic -W clippy::nursery
cargo doc
lint_fix:
@cargo clippy --version
cargo clippy --fix -- -D warnings -W clippy::pedantic -W clippy::nursery

test:
cargo nextest run --all-targets --no-fail-fast

t:test

lox_run:build
cargo run run test.lox
cargo run run test.lox
16 changes: 16 additions & 0 deletions src/builtins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::time::{SystemTime, UNIX_EPOCH};

use crate::interpreter;
use crate::value::EvaluatedValue;

pub fn clock(
_interpreter: &mut interpreter::Interpreter,
_args: &[EvaluatedValue],
) -> Result<EvaluatedValue, String> {
let start = SystemTime::now();
#[allow(clippy::cast_precision_loss)]
start.duration_since(UNIX_EPOCH).map_or_else(
|_| Err("Unable to calculate time since UNIX_EPOC".to_string()),
|since_the_epoch| Ok(EvaluatedValue::Number(since_the_epoch.as_millis() as f64)),
)
}
56 changes: 5 additions & 51 deletions src/eval.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,14 @@
//! Eval module
//!
//! Responsible for evlauting the AST and returning the computed values
//!

use std::fmt::Display;
//! Responsible for evalulating the AST and returning the computed values
//! Only supports simple expressions

use crate::{
eval_parser::{Expr, LiteralAtom, Parser},
lexer::TokenType,
value::EvaluatedValue,
};

/// The value that an expression has evaluated too, this can be a literal.
#[derive(Clone, Debug)]
pub enum EvaluatedValue {
/// String value `"hello"`
String(String),
/// Number value. Note Lox only supports double precision floating point
Number(f64),
/// nil, the unset/null value
Nil,
/// Boolean value `true`/`false`
Bool(bool),
}

impl EvaluatedValue {
pub(crate) const fn is_truthy(&self) -> bool {
match self {
Self::String(_) | Self::Number(_) => true,
Self::Nil => false,
Self::Bool(b) => *b,
}
}
}

impl From<EvaluatedValue> for bool {
fn from(val: EvaluatedValue) -> Self {
match val {
EvaluatedValue::String(_) | EvaluatedValue::Number(_) => true,
EvaluatedValue::Nil => false,
EvaluatedValue::Bool(b) => b,
}
}
}

impl Display for EvaluatedValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::String(s) => write!(f, "{s}"),
Self::Number(n) => write!(f, "{n}"),
Self::Nil => write!(f, "nil"),
Self::Bool(b) => write!(f, "{b:}"),
}
}
}

/// `Eval`
/// an iterator that consumes expressions from the parser and tries to evaluate them.
pub struct Eval<'de> {
Expand Down Expand Up @@ -177,15 +132,14 @@ fn evaluate_expression(expr: Expr) -> Result<EvaluatedValue, String> {
true => Ok(EvaluatedValue::Bool(false)),
false => Ok(EvaluatedValue::Bool(true)),
},
_ => todo!(),
},
),
TokenType::Minus => r.as_ref().map_or_else(
|_| todo!(),
|v| match v {
EvaluatedValue::String(_) => todo!(),
EvaluatedValue::Number(n) => Ok(EvaluatedValue::Number(-n)),
EvaluatedValue::Nil => todo!(),
EvaluatedValue::Bool(_) => todo!(),
_ => todo!(),
},
),
// TODO: Make unrepresentable by narrowing `operator` to `UnaryOperator:Not|Negate`
Expand Down
Loading
Loading