finished renaming to tipi
This commit is contained in:
parent
cad1f8f1ec
commit
9fd0b02380
18 changed files with 55 additions and 53 deletions
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue