all clippys done
This commit is contained in:
parent
0e919983bd
commit
bcd81677bb
9 changed files with 99 additions and 84 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
|
@ -293,32 +293,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crudlang"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"arc-swap",
|
|
||||||
"axum",
|
|
||||||
"chrono",
|
|
||||||
"clap",
|
|
||||||
"dotenv",
|
|
||||||
"log",
|
|
||||||
"log4rs",
|
|
||||||
"notify",
|
|
||||||
"reqwest",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"tokio",
|
|
||||||
"tokio-postgres",
|
|
||||||
"tower",
|
|
||||||
"tower-http",
|
|
||||||
"tower-livereload",
|
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
|
||||||
"url",
|
|
||||||
"walkdir",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
|
@ -1852,6 +1826,32 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tipi-lang"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arc-swap",
|
||||||
|
"axum",
|
||||||
|
"chrono",
|
||||||
|
"clap",
|
||||||
|
"dotenv",
|
||||||
|
"log",
|
||||||
|
"log4rs",
|
||||||
|
"notify",
|
||||||
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-postgres",
|
||||||
|
"tower",
|
||||||
|
"tower-http",
|
||||||
|
"tower-livereload",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"url",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.48.0"
|
version = "1.48.0"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "crudlang"
|
name = "tipi-lang"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
object Person:
|
object Person:
|
||||||
name: string
|
name: string
|
||||||
|
|
||||||
// fn get(path: string) -> string:
|
fn get(path: string) -> string:
|
||||||
// let p = Person(name: path)
|
"hello" + path
|
||||||
// service.add("hello", p.name)
|
|
||||||
|
|
@ -33,3 +33,6 @@ pub fn call(
|
||||||
(self_val, args)
|
(self_val, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn expected(expected_type: &str) -> RuntimeError {
|
||||||
|
RuntimeError::ExpectedType(expected_type.to_string())
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::builtins::{insert, MethodMap};
|
use crate::builtins::{expected, insert, MethodMap};
|
||||||
use crate::errors::RuntimeError;
|
use crate::errors::RuntimeError;
|
||||||
use crate::value::Value;
|
use crate::value::{bool, i64, string, Value};
|
||||||
|
|
||||||
pub(crate) fn string_methods() -> MethodMap {
|
pub(crate) fn string_methods() -> MethodMap {
|
||||||
let mut string_methods: MethodMap = HashMap::new();
|
let mut string_methods: MethodMap = HashMap::new();
|
||||||
let m = &mut string_methods;
|
let m = &mut string_methods;
|
||||||
insert(m, "len", string_len);
|
insert(m, "len", string_len);
|
||||||
insert(m, "to_uppercase", string_to_uppercase);
|
insert(m, "to_uppercase", string_to_uppercase);
|
||||||
|
insert(m, "to_lowercase", string_to_lowercase);
|
||||||
insert(m, "contains", string_contains);
|
insert(m, "contains", string_contains);
|
||||||
insert(m, "reverse", string_reverse);
|
insert(m, "reverse", string_reverse);
|
||||||
string_methods
|
string_methods
|
||||||
|
|
@ -15,24 +16,31 @@ pub(crate) fn string_methods() -> MethodMap {
|
||||||
|
|
||||||
fn string_len(self_val: Value, _args: Vec<Value>) -> Result<Value, RuntimeError> {
|
fn string_len(self_val: Value, _args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
match self_val {
|
match self_val {
|
||||||
Value::String(s) => Ok(Value::I64(s.len() as i64)),
|
Value::String(s) => Ok(i64(s.len() as i64)),
|
||||||
_ => Err(RuntimeError::ExpectedType("string".to_string())),
|
_ => Err(expected_a_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn string_to_uppercase(self_val: Value, _args: Vec<Value>) -> Result<Value, RuntimeError> {
|
fn string_to_uppercase(self_val: Value, _args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
match self_val {
|
match self_val {
|
||||||
Value::String(s) => Ok(Value::String(s.to_uppercase())),
|
Value::String(s) => Ok(string(s.to_uppercase())),
|
||||||
_ => Err(RuntimeError::ExpectedType("string".to_string())),
|
_ => Err(expected_a_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn string_to_lowercase(self_val: Value, _args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
|
match self_val {
|
||||||
|
Value::String(s) => Ok(string(s.to_lowercase())),
|
||||||
|
_ => Err(expected_a_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn string_contains(self_val: Value, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
fn string_contains(self_val: Value, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
match (self_val, args.first()) {
|
match (self_val, args.first()) {
|
||||||
(Value::String(s), Some(Value::String(pat))) => {
|
(Value::String(s), Some(Value::String(pat))) => {
|
||||||
Ok(Value::Bool(s.contains(pat.as_str())))
|
Ok(bool(s.contains(pat.as_str())))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::ExpectedType("string".to_string())),
|
_ => Err(expected_a_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,6 +49,10 @@ fn string_reverse(self_val: Value, _: Vec<Value>) -> Result<Value, RuntimeError>
|
||||||
Value::String(s) => {
|
Value::String(s) => {
|
||||||
Ok(s.chars().rev().collect::<String>().into())
|
Ok(s.chars().rev().collect::<String>().into())
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::ExpectedType("string".to_string())),
|
_ => Err(expected_a_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expected_a_string() -> RuntimeError {
|
||||||
|
expected("string")
|
||||||
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ pub(crate) fn compile_function(
|
||||||
|
|
||||||
compiler.vars.insert(name, var_index);
|
compiler.vars.insert(name, var_index);
|
||||||
}
|
}
|
||||||
let mut chunk = compiler.compile(&function.body, symbols, registry, namespace)?;
|
let mut chunk = compiler.compile(&function.body, symbols, registry, namespace)?.chunk;
|
||||||
chunk.function_parameters = function.parameters.to_vec();
|
chunk.function_parameters = function.parameters.to_vec();
|
||||||
Ok(chunk)
|
Ok(chunk)
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ pub(crate) fn compile_in_namespace(
|
||||||
) -> Result<(), CompilerErrorAtLine> {
|
) -> Result<(), CompilerErrorAtLine> {
|
||||||
let name = namespace.unwrap_or("main");
|
let name = namespace.unwrap_or("main");
|
||||||
let compiler = Compiler::new(name);
|
let compiler = Compiler::new(name);
|
||||||
let chunk = compiler.compile(ast, symbols, registry, name)?;
|
let chunk = compiler.compile(ast, symbols, registry, name)?.chunk;
|
||||||
let qname = if let Some(namespace) = namespace {
|
let qname = if let Some(namespace) = namespace {
|
||||||
format!("{}/{}", namespace, "main")
|
format!("{}/{}", namespace, "main")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -62,7 +62,7 @@ pub(crate) fn compile_in_namespace(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Compiler {
|
pub(crate) struct Compiler {
|
||||||
chunk: Chunk,
|
chunk: Chunk,
|
||||||
_had_error: bool,
|
_had_error: bool,
|
||||||
current_line: usize,
|
current_line: usize,
|
||||||
|
|
@ -70,7 +70,7 @@ struct Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Compiler {
|
impl Compiler {
|
||||||
fn new(name: &str) -> Self {
|
pub(crate) fn new(name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
chunk: Chunk::new(name),
|
chunk: Chunk::new(name),
|
||||||
_had_error: false,
|
_had_error: false,
|
||||||
|
|
@ -79,19 +79,19 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile(
|
pub(crate) fn compile(
|
||||||
mut self,
|
mut self,
|
||||||
ast: &Vec<Statement>,
|
ast: &Vec<Statement>,
|
||||||
symbols: &SymbolTable,
|
symbols: &SymbolTable,
|
||||||
registry: &mut Registry,
|
registry: &mut Registry,
|
||||||
namespace: &str,
|
namespace: &str,
|
||||||
) -> Result<Chunk, CompilerErrorAtLine> {
|
) -> Result<Self, CompilerErrorAtLine> {
|
||||||
for statement in ast {
|
for statement in ast {
|
||||||
self.compile_statement(statement, symbols, registry, namespace)?;
|
self.compile_statement(statement, symbols, registry, namespace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.emit_byte(OP_RETURN);
|
self.emit_byte(OP_RETURN);
|
||||||
Ok(self.chunk)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raise(&self, error: CompilerError) -> CompilerErrorAtLine {
|
fn raise(&self, error: CompilerError) -> CompilerErrorAtLine {
|
||||||
|
|
@ -223,7 +223,7 @@ impl Compiler {
|
||||||
if let Some(name_index) = name_index {
|
if let Some(name_index) = name_index {
|
||||||
self.emit_bytes(OP_GET, *name_index as u16);
|
self.emit_bytes(OP_GET, *name_index as u16);
|
||||||
} else {
|
} else {
|
||||||
return Err(self.raise(CompilerError::UndeclaredVariable(name.to_string())));
|
return Err(self.raise(UndeclaredVariable(name.to_string())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::Literal { value, .. } => {
|
Expression::Literal { value, .. } => {
|
||||||
|
|
|
||||||
14
src/main.rs
14
src/main.rs
|
|
@ -3,10 +3,10 @@ use axum::http::StatusCode;
|
||||||
use axum::routing::any;
|
use axum::routing::any;
|
||||||
use axum::{Json, Router};
|
use axum::{Json, Router};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use crudlang::chunk::Chunk;
|
use tipi_lang::chunk::Chunk;
|
||||||
use crudlang::errors::CrudLangError;
|
use tipi_lang::errors::CrudLangError;
|
||||||
use crudlang::vm::interpret_async;
|
use tipi_lang::vm::interpret_async;
|
||||||
use crudlang::{compile_sourcedir, map_underlying};
|
use tipi_lang::{compile_sourcedir, map_underlying};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
|
|
@ -37,7 +37,7 @@ async fn main() -> Result<(), CrudLangError> {
|
||||||
let swap = Arc::new(ArcSwap::from(Arc::new(registry)));
|
let swap = Arc::new(ArcSwap::from(Arc::new(registry)));
|
||||||
if !empty {
|
if !empty {
|
||||||
if args.watch {
|
if args.watch {
|
||||||
crudlang::file_watch::start_watch_daemon(&source, swap.clone());
|
tipi_lang::file_watch::start_watch_daemon(&source, swap.clone());
|
||||||
}
|
}
|
||||||
println!("-- Compilation successful --");
|
println!("-- Compilation successful --");
|
||||||
let state =AppState {
|
let state =AppState {
|
||||||
|
|
@ -57,14 +57,14 @@ async fn main() -> Result<(), CrudLangError> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if args.repl {
|
if args.repl {
|
||||||
std::thread::spawn(move || crudlang::repl::start(swap.clone()).unwrap());
|
std::thread::spawn(move || tipi_lang::repl::start(swap.clone()).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
axum::serve(listener, app).await.map_err(map_underlying())?;
|
axum::serve(listener, app).await.map_err(map_underlying())?;
|
||||||
} else {
|
} else {
|
||||||
println!("No source files found or compilation error");
|
println!("No source files found or compilation error");
|
||||||
if args.repl {
|
if args.repl {
|
||||||
crudlang::repl::start(swap.clone())?;
|
tipi_lang::repl::start(swap.clone())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
14
src/value.rs
14
src/value.rs
|
|
@ -9,7 +9,7 @@ use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Shl, Shr, Sub};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Object {
|
pub struct Object {
|
||||||
pub(crate) definition: String,
|
pub(crate) definition: String,
|
||||||
pub(crate) fields: Vec<(String,Value)>,
|
pub(crate) fields: Vec<(String, Value)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -32,6 +32,18 @@ pub enum Value {
|
||||||
Void,
|
Void,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn string(v: impl Into<String>) -> Value {
|
||||||
|
Value::String(v.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn i64(v: impl Into<i64>) -> Value {
|
||||||
|
Value::I64(v.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn bool(v: impl Into<bool>) -> Value {
|
||||||
|
Value::Bool(v.into())
|
||||||
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn cast_u32(self) -> Result<Self, ValueError> {
|
pub fn cast_u32(self) -> Result<Self, ValueError> {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
47
src/vm.rs
47
src/vm.rs
|
|
@ -7,31 +7,23 @@ use arc_swap::Guard;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
use crate::Registry;
|
||||||
|
|
||||||
pub struct Vm {
|
pub struct Vm {
|
||||||
ip: usize,
|
ip: usize,
|
||||||
stack: Vec<Value>,
|
stack: Vec<Value>,
|
||||||
local_vars: HashMap<String, Value>,
|
local_vars: HashMap<String, Value>,
|
||||||
error_occurred: bool,
|
error_occurred: bool,
|
||||||
registry: Arc<HashMap<String, Chunk>>,
|
pub(crate) registry: Arc<HashMap<String, Chunk>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn interpret(
|
pub fn interpret(
|
||||||
registry: Guard<Arc<HashMap<String, Chunk>>>,
|
registry: Guard<Arc<HashMap<String, Chunk>>>,
|
||||||
function: &str,
|
function: &str,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
let chunk = registry.get(function).unwrap().clone();
|
let chunk = registry.get(function).unwrap().clone();
|
||||||
// for (key,value) in registry.iter() {
|
let mut vm = Vm::new(®istry);
|
||||||
// println!("{}", key);
|
|
||||||
// value.disassemble();
|
|
||||||
// }
|
|
||||||
let mut vm = Vm {
|
|
||||||
ip: 0,
|
|
||||||
stack: vec![],
|
|
||||||
local_vars: HashMap::new(),
|
|
||||||
error_occurred: false,
|
|
||||||
registry: registry.clone(),
|
|
||||||
};
|
|
||||||
vm.run(&get_context(function), &chunk)
|
vm.run(&get_context(function), &chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,13 +36,7 @@ pub async fn interpret_async(
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
let chunk = registry.get(function);
|
let chunk = registry.get(function);
|
||||||
if let Some(chunk) = chunk {
|
if let Some(chunk) = chunk {
|
||||||
let mut vm = Vm {
|
let mut vm = Vm::new(®istry);
|
||||||
ip: 0,
|
|
||||||
stack: vec![],
|
|
||||||
local_vars: HashMap::new(),
|
|
||||||
error_occurred: false,
|
|
||||||
registry: registry.clone(),
|
|
||||||
};
|
|
||||||
vm.local_vars
|
vm.local_vars
|
||||||
.insert("path".to_string(), Value::String(uri.into()));
|
.insert("path".to_string(), Value::String(uri.into()));
|
||||||
vm.local_vars
|
vm.local_vars
|
||||||
|
|
@ -71,18 +57,21 @@ fn value_map(strings: HashMap<String, String>) -> HashMap<Value, Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpret_function(chunk: &Chunk, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
pub fn interpret_function(chunk: &Chunk, args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
let mut vm = Vm {
|
let mut vm = Vm::new(& Arc::new(HashMap::new()));
|
||||||
ip: 0,
|
|
||||||
stack: vec![],
|
|
||||||
local_vars: HashMap::new(),
|
|
||||||
error_occurred: false,
|
|
||||||
registry: Arc::new(HashMap::new()),
|
|
||||||
};
|
|
||||||
|
|
||||||
vm.run_function(chunk, args)
|
vm.run_function(chunk, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vm {
|
impl Vm {
|
||||||
|
pub(crate) fn new(registry: &Arc<Registry>) -> Self {
|
||||||
|
Self {
|
||||||
|
ip: 0,
|
||||||
|
stack: vec![],
|
||||||
|
local_vars: HashMap::new(),
|
||||||
|
error_occurred: false,
|
||||||
|
registry: registry.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn run_function(&mut self, chunk: &Chunk, mut args: Vec<Value>) -> Result<Value, RuntimeError> {
|
fn run_function(&mut self, chunk: &Chunk, mut args: Vec<Value>) -> Result<Value, RuntimeError> {
|
||||||
// arguments -> locals
|
// arguments -> locals
|
||||||
for (_, name) in chunk.vars.iter() {
|
for (_, name) in chunk.vars.iter() {
|
||||||
|
|
@ -91,7 +80,7 @@ impl Vm {
|
||||||
self.run("", chunk)
|
self.run("", chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&mut self, context: &str, chunk: &Chunk) -> Result<Value, RuntimeError> {
|
pub(crate) fn run(&mut self, context: &str, chunk: &Chunk) -> Result<Value, RuntimeError> {
|
||||||
loop {
|
loop {
|
||||||
if self.error_occurred {
|
if self.error_occurred {
|
||||||
return Err(Something);
|
return Err(Something);
|
||||||
|
|
@ -313,7 +302,7 @@ fn unary_op(stack: &mut Vm, op: impl Fn(&Value) -> Result<Value, ValueError> + C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_context(path: &str) -> String {
|
pub(crate) fn get_context(path: &str) -> String {
|
||||||
let mut parts: Vec<&str> = path.split('/').collect();
|
let mut parts: Vec<&str> = path.split('/').collect();
|
||||||
if parts.len() >= 2 {
|
if parts.len() >= 2 {
|
||||||
parts.truncate(parts.len() - 2);
|
parts.truncate(parts.len() - 2);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue