bugs in print, global functions wip running fibonacci
This commit is contained in:
parent
f4de9d1158
commit
cd409c0897
10 changed files with 78 additions and 51 deletions
6
examples/fibonacci/fib.tp
Normal file
6
examples/fibonacci/fib.tp
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
println("Fibonacci sequence:")
|
||||||
|
let fib = [1,1]
|
||||||
|
|
||||||
|
for i in 2..10:
|
||||||
|
fib.push(fib[i-2] + fib[i-1])
|
||||||
|
println(fib)
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
use crate::builtins::{FunctionMap, Signature, add};
|
use crate::builtins::{FunctionMap, Signature, add};
|
||||||
use crate::compiler::tokens::TokenType::{DateTime, Void};
|
use crate::compiler::tokens::TokenType::{DateTime, StringType, Void};
|
||||||
use crate::errors::RuntimeError;
|
use crate::errors::RuntimeError;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
use crate::compiler::ast_pass::Parameter;
|
||||||
|
|
||||||
pub(crate) static GLOBAL_FUNCTIONS: LazyLock<FunctionMap> = LazyLock::new(|| {
|
pub(crate) static GLOBAL_FUNCTIONS: LazyLock<FunctionMap> = LazyLock::new(|| {
|
||||||
let mut global_functions: FunctionMap = HashMap::new();
|
let mut global_functions: FunctionMap = HashMap::new();
|
||||||
let functions = &mut global_functions;
|
let functions = &mut global_functions;
|
||||||
add(functions, "now", Signature::new(vec![], DateTime, now));
|
add(functions, "now", Signature::new(vec![], DateTime, now));
|
||||||
add(functions, "print", Signature::new(vec![], Void, print));
|
add(functions, "print", Signature::new(vec![Parameter::new("text", StringType)], Void, print));
|
||||||
add(functions, "println", Signature::new(vec![], Void, println));
|
add(functions, "println", Signature::new(vec![Parameter::new("text", StringType)], Void, println));
|
||||||
|
|
||||||
global_functions
|
global_functions
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,7 @@ impl AsmPass {
|
||||||
// maybe global function
|
// maybe global function
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(fun) = GLOBAL_FUNCTIONS.get(name) {
|
if let Some(fun) = GLOBAL_FUNCTIONS.get(name) {
|
||||||
|
self.get_arguments_in_order(namespace, symbols, registry, arguments, &fun.parameters)?;
|
||||||
self.emit(Call(name_index, fun.arity()));
|
self.emit(Call(name_index, fun.arity()));
|
||||||
} else {
|
} else {
|
||||||
return Err(
|
return Err(
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,7 @@ pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, TipiLangError> {
|
||||||
Ok(asm_registry)
|
Ok(asm_registry)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
pub fn run(src: &str) -> Result<crate::value::Value, TipiLangError> {
|
||||||
pub(crate) fn run(src: &str) -> Result<crate::value::Value, TipiLangError> {
|
|
||||||
let tokens = scan_pass::scan(src)?;
|
let tokens = scan_pass::scan(src)?;
|
||||||
let mut symbol_table = HashMap::new();
|
let mut symbol_table = HashMap::new();
|
||||||
let ast = ast_pass::compile(None, tokens, &mut symbol_table)?;
|
let ast = ast_pass::compile(None, tokens, &mut symbol_table)?;
|
||||||
|
|
|
||||||
34
src/main.rs
34
src/main.rs
|
|
@ -1,16 +1,17 @@
|
||||||
|
use arc_swap::ArcSwap;
|
||||||
use axum::extract::{Request, State};
|
use axum::extract::{Request, State};
|
||||||
use axum::http::StatusCode;
|
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 log::info;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tipi_lang::compiler::assembly_pass::AsmChunk;
|
||||||
|
use tipi_lang::compiler::{compile, compile_sourcedir, map_underlying, run};
|
||||||
use tipi_lang::errors::TipiLangError;
|
use tipi_lang::errors::TipiLangError;
|
||||||
use tipi_lang::vm::interpret_async;
|
use tipi_lang::vm::interpret_async;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use arc_swap::ArcSwap;
|
|
||||||
use log::info;
|
|
||||||
use tipi_lang::compiler::assembly_pass::AsmChunk;
|
|
||||||
use tipi_lang::compiler::{compile_sourcedir, map_underlying};
|
|
||||||
|
|
||||||
/// A simple CLI tool to greet users
|
/// A simple CLI tool to greet users
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
|
|
@ -23,13 +24,20 @@ struct Args {
|
||||||
|
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
watch: bool,
|
watch: bool,
|
||||||
|
|
||||||
|
#[arg(short, long)]
|
||||||
|
file: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), TipiLangError> {
|
async fn main() -> Result<(), TipiLangError> {
|
||||||
println!("-- Tipilang --");
|
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
if let Some(file) = args.file {
|
||||||
|
let source = fs::read_to_string(file).expect("Unable to read file");
|
||||||
|
run(&source)?;
|
||||||
|
} else {
|
||||||
|
println!("-- Tipilang --");
|
||||||
let source = args.source.unwrap_or("./source".to_string());
|
let source = args.source.unwrap_or("./source".to_string());
|
||||||
let registry = compile_sourcedir(&source)?;
|
let registry = compile_sourcedir(&source)?;
|
||||||
let empty = registry.is_empty();
|
let empty = registry.is_empty();
|
||||||
|
|
@ -40,7 +48,7 @@ async fn main() -> Result<(), TipiLangError> {
|
||||||
tipi_lang::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 {
|
||||||
registry: swap.clone(),
|
registry: swap.clone(),
|
||||||
};
|
};
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
|
|
@ -67,6 +75,7 @@ async fn main() -> Result<(), TipiLangError> {
|
||||||
tipi_lang::repl::start(swap.clone())?;
|
tipi_lang::repl::start(swap.clone())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,7 +108,7 @@ async fn handle_any(
|
||||||
headers.insert(k.to_string(), v.to_str().unwrap().to_string());
|
headers.insert(k.to_string(), v.to_str().unwrap().to_string());
|
||||||
}
|
}
|
||||||
let path = &req.uri().to_string();
|
let path = &req.uri().to_string();
|
||||||
info!("invoked {:?} => {}",req, function_qname);
|
info!("invoked {:?} => {}", req, function_qname);
|
||||||
match interpret_async(
|
match interpret_async(
|
||||||
state.registry.load(),
|
state.registry.load(),
|
||||||
&function_qname,
|
&function_qname,
|
||||||
|
|
@ -112,7 +121,12 @@ async fn handle_any(
|
||||||
Ok(value) => Ok(Json(value.to_string())),
|
Ok(value) => Ok(Json(value.to_string())),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// url checks out but function for method not found
|
// url checks out but function for method not found
|
||||||
if state.registry.load().get(&format!("{}.main", component)).is_some() {
|
if state
|
||||||
|
.registry
|
||||||
|
.load()
|
||||||
|
.get(&format!("{}.main", component))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
Err(StatusCode::METHOD_NOT_ALLOWED)
|
Err(StatusCode::METHOD_NOT_ALLOWED)
|
||||||
} else {
|
} else {
|
||||||
Err(StatusCode::NOT_FOUND)
|
Err(StatusCode::NOT_FOUND)
|
||||||
|
|
|
||||||
10
src/vm.rs
10
src/vm.rs
|
|
@ -156,10 +156,14 @@ impl Vm {
|
||||||
self.push(value);
|
self.push(value);
|
||||||
}
|
}
|
||||||
Op::ListGet => {
|
Op::ListGet => {
|
||||||
let index = self.pop();
|
let index = self.pop().cast_usize()?;
|
||||||
let list = self.pop();
|
let list = self.pop();
|
||||||
if let Value::List(list) = list {
|
if let Value::List(list) = list {
|
||||||
self.push(list.get(index.cast_usize()?).cloned().unwrap())
|
if list.len() <= index {
|
||||||
|
return Err(RuntimeError::IndexOutOfBounds(list.len(), index));
|
||||||
|
} else {
|
||||||
|
self.push(list.get(index).cloned().unwrap())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Op::CallBuiltin(function_name_index, function_type_index, num_args) => {
|
Op::CallBuiltin(function_name_index, function_type_index, num_args) => {
|
||||||
|
|
@ -252,8 +256,10 @@ impl Vm {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, value: Value) {
|
fn push(&mut self, value: Value) {
|
||||||
|
if value != Value::Void {
|
||||||
self.stack.push(value);
|
self.stack.push(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pop(&mut self) -> Value {
|
fn pop(&mut self) -> Value {
|
||||||
self.stack
|
self.stack
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue