finished renaming to tipi

This commit is contained in:
Shautvast 2025-11-21 16:16:10 +01:00
parent cad1f8f1ec
commit 9fd0b02380
18 changed files with 55 additions and 53 deletions

View file

@ -22,11 +22,11 @@ Borrowing from that: 'the place where http lives'.
- collection literals - collection literals
- ease of use for CRUD operations, like automatic mapping from sql rows to json - ease of use for CRUD operations, like automatic mapping from sql rows to json
- Urls are made up of directories. - Urls are made up of directories.
- A controller sourcefile is a file named web.crud - A controller sourcefile is a file named web.tp
- likewise: - likewise:
- service.crud for services - service.tp for services
- db.crud database access code - db.tp database access code
- util.crud utilities - util.tp utilities
- it is not mandatory to have services. If you want, you can put all your logic in a controller. - it is not mandatory to have services. If you want, you can put all your logic in a controller.
- and it can only access functions in its own subtree. Generic code should be put higher up in the tree. - and it can only access functions in its own subtree. Generic code should be put higher up in the tree.
- Therefore, services cannot call other services, because that is the recipe for spaghetti. Refactor your logic, abstract and put lower level code in utilities. - Therefore, services cannot call other services, because that is the recipe for spaghetti. Refactor your logic, abstract and put lower level code in utilities.

View file

@ -2,7 +2,7 @@
mod tests { mod tests {
use crate::errors::CompilerError::IllegalArgumentsException; use crate::errors::CompilerError::IllegalArgumentsException;
use crate::errors::CompilerErrorAtLine; use crate::errors::CompilerErrorAtLine;
use crate::errors::CrudLangError::{Compiler, Runtime}; use crate::errors::TipiLangError::{Compiler, Runtime};
use crate::errors::RuntimeError::{IllegalArgumentException, IndexOutOfBounds}; use crate::errors::RuntimeError::{IllegalArgumentException, IndexOutOfBounds};
use crate::value::{Value, string}; use crate::value::{Value, string};
use chrono::DateTime; use chrono::DateTime;

View file

@ -1,10 +1,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; use std::fs;
use walkdir::WalkDir; use walkdir::WalkDir;
use crate::{compiler, symbol_builder, AsmRegistry}; use crate::{compiler, symbol_builder, AsmRegistry, TIPI_EXT};
use crate::compiler::asm_pass::AsmChunk; use crate::compiler::asm_pass::AsmChunk;
use crate::errors::CrudLangError; use crate::errors::TipiLangError;
use crate::errors::CrudLangError::Platform; use crate::errors::TipiLangError::Platform;
mod compiler_tests; mod compiler_tests;
pub mod scan_pass; pub mod scan_pass;
@ -12,19 +12,19 @@ pub mod ast_pass;
pub mod tokens; pub mod tokens;
pub mod asm_pass; pub mod asm_pass;
pub fn compile_sourcedir(source_dir: &str) -> Result<HashMap<String, AsmChunk>, CrudLangError> { pub fn compile_sourcedir(source_dir: &str) -> Result<HashMap<String, AsmChunk>, TipiLangError> {
let mut asm_registry = AsmRegistry::new(); let mut asm_registry = AsmRegistry::new();
for entry in WalkDir::new(source_dir).into_iter().filter_map(|e| e.ok()) { for entry in WalkDir::new(source_dir).into_iter().filter_map(|e| e.ok()) {
let path = entry.path().to_str().unwrap(); let path = entry.path().to_str().unwrap();
if path.ends_with(".crud") { if path.ends_with(TIPI_EXT) {
print!("-- Compiling {} -- ", path); print!("-- Compiling {} -- ", path);
let source = fs::read_to_string(path).map_err(map_underlying())?; let source = fs::read_to_string(path).map_err(map_underlying())?;
let tokens = scan_pass::scan(&source)?; let tokens = scan_pass::scan(&source)?;
let mut symbol_table = HashMap::new(); let mut symbol_table = HashMap::new();
match ast_pass::compile(Some(path), tokens, &mut symbol_table) { match ast_pass::compile(Some(path), tokens, &mut symbol_table) {
Ok(statements) => { Ok(statements) => {
let path = path.strip_prefix(source_dir).unwrap().replace(".crud", ""); let path = path.strip_prefix(source_dir).unwrap().replace(TIPI_EXT, "");
symbol_builder::build(&path, &statements, &mut symbol_table); symbol_builder::build(&path, &statements, &mut symbol_table);
asm_pass::compile(Some(&path), &statements, &symbol_table, &mut asm_registry)?; asm_pass::compile(Some(&path), &statements, &symbol_table, &mut asm_registry)?;
@ -40,12 +40,12 @@ pub fn compile_sourcedir(source_dir: &str) -> Result<HashMap<String, AsmChunk>,
Ok(asm_registry) Ok(asm_registry)
} }
pub fn map_underlying() -> fn(std::io::Error) -> CrudLangError { pub fn map_underlying() -> fn(std::io::Error) -> TipiLangError {
|e| Platform(e.to_string()) |e| Platform(e.to_string())
} }
pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, CrudLangError> { pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, TipiLangError> {
let tokens = compiler::scan_pass::scan(src)?; let tokens = compiler::scan_pass::scan(src)?;
let mut asm_registry = HashMap::new(); let mut asm_registry = HashMap::new();
let mut symbol_table = HashMap::new(); let mut symbol_table = HashMap::new();
@ -56,7 +56,7 @@ pub fn compile(src: &str) -> Result<HashMap<String, AsmChunk>, CrudLangError> {
} }
#[cfg(test)] #[cfg(test)]
pub(crate) fn run(src: &str) -> Result<crate::value::Value, CrudLangError> { pub(crate) fn run(src: &str) -> Result<crate::value::Value, TipiLangError> {
let tokens = compiler::scan_pass::scan(src)?; let tokens = compiler::scan_pass::scan(src)?;
let mut symbol_table = HashMap::new(); let mut symbol_table = HashMap::new();
let ast = compiler::ast_pass::compile(None, tokens, &mut symbol_table)?; let ast = compiler::ast_pass::compile(None, tokens, &mut symbol_table)?;
@ -64,5 +64,5 @@ pub(crate) fn run(src: &str) -> Result<crate::value::Value, CrudLangError> {
let mut asm_registry = HashMap::new(); let mut asm_registry = HashMap::new();
asm_pass::compile(None, &ast, &symbol_table, &mut asm_registry)?; asm_pass::compile(None, &ast, &symbol_table, &mut asm_registry)?;
let registry = arc_swap::ArcSwap::from(std::sync::Arc::new(asm_registry)); let registry = arc_swap::ArcSwap::from(std::sync::Arc::new(asm_registry));
crate::vm::interpret(registry.load(), "main").map_err(CrudLangError::from) crate::vm::interpret(registry.load(), "main").map_err(TipiLangError::from)
} }

View file

@ -3,7 +3,7 @@ use std::fmt::Display;
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug, PartialEq)] #[derive(Error, Debug, PartialEq)]
pub enum CrudLangError { pub enum TipiLangError {
#[error("Compilation failed: {0}")] #[error("Compilation failed: {0}")]
Compiler(#[from] CompilerErrorAtLine), Compiler(#[from] CompilerErrorAtLine),
@ -61,7 +61,7 @@ pub enum CompilerError {
UnexpectedType(TokenType), UnexpectedType(TokenType),
#[error("'{0}' is a keyword. You cannot use it as an identifier")] #[error("'{0}' is a keyword. You cannot use it as an identifier")]
KeywordNotAllowedAsIdentifier(TokenType), KeywordNotAllowedAsIdentifier(TokenType),
#[error("Crud does not support numbers above 2^64")] #[error("Tipi does not support numbers above 2^64")]
Overflow, Overflow,
#[error("Undeclared function: '{0}'")] #[error("Undeclared function: '{0}'")]
FunctionNotFound(String), FunctionNotFound(String),

View file

@ -18,3 +18,5 @@ pub(crate) type SymbolTable = HashMap<String, Symbol>;
pub(crate) type Expr = Result<Expression, CompilerErrorAtLine>; pub(crate) type Expr = Result<Expression, CompilerErrorAtLine>;
pub(crate) type Stmt = Result<Statement, CompilerErrorAtLine>; pub(crate) type Stmt = Result<Statement, CompilerErrorAtLine>;
pub(crate) type AsmRegistry = HashMap<String, AsmChunk>; pub(crate) type AsmRegistry = HashMap<String, AsmChunk>;
pub const TIPI_EXT: &str = ".tp";

View file

@ -3,7 +3,7 @@ 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 tipi_lang::errors::CrudLangError; use tipi_lang::errors::TipiLangError;
use tipi_lang::vm::interpret_async; use tipi_lang::vm::interpret_async;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
@ -26,8 +26,8 @@ struct Args {
} }
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), CrudLangError> { async fn main() -> Result<(), TipiLangError> {
println!("-- Crudlang --"); println!("-- Tipilang --");
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
let args = Args::parse(); let args = Args::parse();
let source = args.source.unwrap_or("./source".to_string()); let source = args.source.unwrap_or("./source".to_string());

View file

@ -32,7 +32,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}; };
let app = Router::new() let app = Router::new()
.route("/api/customers/{id}", get(get_customer)) .route("/api/customers.tp/{id}", get(get_customer))
.with_state(state); .with_state(state);
// run our app with hyper, listening globally on port 3000 // run our app with hyper, listening globally on port 3000
@ -53,7 +53,7 @@ async fn get_customer(
let rows = state let rows = state
.db .db
.query( .query(
"SELECT id, first_name, last_name FROM customers WHERE id = $1", "SELECT id, first_name, last_name FROM customers.tp WHERE id = $1",
&[&id], &[&id],
) )
.await .await

View file

@ -1,7 +1,7 @@
use crate::compiler::asm_pass::AsmChunk; use crate::compiler::asm_pass::AsmChunk;
use crate::compiler::scan_pass::scan; use crate::compiler::scan_pass::scan;
use crate::compiler::{asm_pass, ast_pass, map_underlying}; use crate::compiler::{asm_pass, ast_pass, map_underlying};
use crate::errors::CrudLangError; use crate::errors::TipiLangError;
use crate::symbol_builder; use crate::symbol_builder;
use crate::vm::Vm; use crate::vm::Vm;
use arc_swap::ArcSwap; use arc_swap::ArcSwap;
@ -11,7 +11,7 @@ use std::io::Write;
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
pub fn start(registry: Arc<ArcSwap<HashMap<String, AsmChunk>>>) -> Result<(), CrudLangError> { pub fn start(registry: Arc<ArcSwap<HashMap<String, AsmChunk>>>) -> Result<(), TipiLangError> {
println!("REPL started -- Type ctrl-c to exit (both the repl and the server)"); println!("REPL started -- Type ctrl-c to exit (both the repl and the server)");
println!(":h for help"); println!(":h for help");
let mut symbol_table = HashMap::new(); let mut symbol_table = HashMap::new();

View file

@ -1,6 +1,6 @@
# Change Log # Change Log
All notable changes to the "crud" extension will be documented in this file. All notable changes to the "tipi" extension will be documented in this file.
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

View file

@ -1,7 +1,7 @@
{ {
"name": "crud", "name": "tipi",
"displayName": "crud", "displayName": "tipi",
"description": "crud-lang", "description": "tipi-lang",
"version": "0.0.1", "version": "0.0.1",
"engines": { "engines": {
"vscode": "^1.105.0" "vscode": "^1.105.0"
@ -11,20 +11,20 @@
], ],
"contributes": { "contributes": {
"languages": [{ "languages": [{
"id": "crud", "id": "tipi",
"aliases": ["crud-lang", "crud"], "aliases": ["tipi-lang", "tipi"],
"extensions": [".crud"], "extensions": [".tipi"],
"configuration": "./language-configuration.json" "configuration": "./language-configuration.json"
}], }],
"grammars": [{ "grammars": [{
"language": "crud", "language": "tipi",
"scopeName": "source.crud", "scopeName": "source.tipi",
"path": "./syntaxes/crud.tmLanguage.json" "path": "./syntaxes/tipi.tmLanguage.json"
}], }],
"semanticTokenScopes": [ "semanticTokenScopes": [
{ {
"scopes": { "scopes": {
"crud.custom.scope": ["annotation.crud"] "tipi.custom.scope": ["annotation.tipi"]
} }
} }
] ]

View file

@ -1,6 +1,6 @@
{ {
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
"name": "crud-lang", "name": "tipi-lang",
"patterns": [ "patterns": [
{ {
"include": "#keywords" "include": "#keywords"
@ -19,35 +19,35 @@
"keywords": { "keywords": {
"patterns": [ "patterns": [
{ {
"name": "variable.other.crud", "name": "variable.other.tipi",
"match": "(#.+?\\(.*?\\))" "match": "(#.+?\\(.*?\\))"
}, },
{ {
"name": "keyword.control.crud", "name": "keyword.control.tipi",
"match": "\\b(fn)\\b" "match": "\\b(fn)\\b"
}, },
{ {
"name": "storage.type.crud", "name": "storage.type.tipi",
"match": "\\b(u32|u64|i32|i64\f32|f64|string|date|char|list|map|bool)\\b" "match": "\\b(u32|u64|i32|i64\f32|f64|string|date|char|list|map|bool)\\b"
}, },
{ {
"name": "support.function.crud", "name": "support.function.tipi",
"match": "\\b(get|put|post|delete|patch|options)\\b" "match": "\\b(get|put|post|delete|patch|options)\\b"
}, },
{ {
"name": "constant.numeric.crud", "name": "constant.numeric.tipi",
"match": "\\b[0-9]+\\.?[0-9]*\\b" "match": "\\b[0-9]+\\.?[0-9]*\\b"
}, },
{ {
"name": "constant.language.crud", "name": "constant.language.tipi",
"match": "\\b(true|false)\\b" "match": "\\b(true|false)\\b"
}, },
{ {
"name": "constant.character.escape.crud", "name": "constant.character.escape.tipi",
"match": "\\\\[nrt\\\\'\"]" "match": "\\\\[nrt\\\\'\"]"
}, },
{ {
"name": "comment.line.crud", "name": "comment.line.tipi",
"match": "(//.*)" "match": "(//.*)"
} }
] ]
@ -55,41 +55,41 @@
"operators": { "operators": {
"patterns": [ "patterns": [
{ {
"name": "keyword.operator.arithmetic.crud", "name": "keyword.operator.arithmetic.tipi",
"match": "\\+|\\-|\\*|\\/" "match": "\\+|\\-|\\*|\\/"
}, },
{ {
"name": "keyword.operator.comparison.crud", "name": "keyword.operator.comparison.tipi",
"match": "==|!=|<=|>=|<|>" "match": "==|!=|<=|>=|<|>"
}, },
{ {
"name": "keyword.operator.assignment.crud", "name": "keyword.operator.assignment.tipi",
"match": "=" "match": "="
} }
] ]
}, },
"strings": { "strings": {
"name": "string.quoted.double.crud", "name": "string.quoted.double.tipi",
"begin": "\"", "begin": "\"",
"end": "\"", "end": "\"",
"patterns": [ "patterns": [
{ {
"name": "constant.character.escape.crud", "name": "constant.character.escape.tipi",
"match": "\\\\." "match": "\\\\."
} }
] ]
}, },
"chars": { "chars": {
"name": "string.quoted.single.crud", "name": "string.quoted.single.tipi",
"begin": "'", "begin": "'",
"end": "'", "end": "'",
"patterns": [ "patterns": [
{ {
"name": "constant.character.escape.crud", "name": "constant.character.escape.tipi",
"match": "\\\\." "match": "\\\\."
} }
] ]
} }
}, },
"scopeName": "source.crud" "scopeName": "source.tipi"
} }

View file

@ -4,7 +4,7 @@
* This folder contains all of the files necessary for your extension. * This folder contains all of the files necessary for your extension.
* `package.json` - this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension. * `package.json` - this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension.
* `syntaxes/crud.tmLanguage.json` - this is the Text mate grammar file that is used for tokenization. * `syntaxes/tipi.tmLanguage.json` - this is the Text mate grammar file that is used for tokenization.
* `language-configuration.json` - this is the language configuration, defining the tokens that are used for comments and brackets. * `language-configuration.json` - this is the language configuration, defining the tokens that are used for comments and brackets.
## Get up and running straight away ## Get up and running straight away