finished yard
This commit is contained in:
parent
a506f51f71
commit
1b62b0fc4e
|
@ -0,0 +1,24 @@
|
||||||
|
@pragma(once)
|
||||||
|
|
||||||
|
@feature(conv, math)
|
||||||
|
@author(Sven Vogel)
|
||||||
|
|
||||||
|
floor(x:rat) = rat {
|
||||||
|
to_rat(to_int(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
round(x:rat) = rat {
|
||||||
|
to_rat(to_int(x + 0.5))
|
||||||
|
}
|
||||||
|
|
||||||
|
ceil(x:rat) = rat {
|
||||||
|
to_rat(to_int(x + 1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fract(x:rat) = rat {
|
||||||
|
x - floor(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
log(x:rat, b:rat) = rat {
|
||||||
|
log(x) / log(b)
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/// module for builtin functons
|
||||||
|
/// and the SENI-module
|
||||||
|
use crate::{parser::data::{Declr, Func}, vmrt::Data};
|
||||||
|
|
||||||
|
use self::modules::Module;
|
||||||
|
|
||||||
|
pub mod modules;
|
||||||
|
|
||||||
|
type Function = &'static dyn Fn(&[Data]) -> Result<Option<Data>, ()>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BuiltinFun {
|
||||||
|
declr: Declr<'static>,
|
||||||
|
func: Function
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuiltinFun {
|
||||||
|
|
||||||
|
pub fn declr(&self) -> Declr<'static> {
|
||||||
|
self.declr.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn func(&self) -> crate::parser::data::Func<'static> {
|
||||||
|
Func {
|
||||||
|
expr: None,
|
||||||
|
is_builtin: true,
|
||||||
|
raw: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_function(&self) -> Function {
|
||||||
|
self.func
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_builtin_funs(mods: &[Module]) -> Vec<BuiltinFun> {
|
||||||
|
let mut funs = vec![
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("say_hello", vec![], None),
|
||||||
|
func: &say_hello
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
funs.append(&mut modules::get_submodules(mods));
|
||||||
|
|
||||||
|
return funs;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn say_hello(_args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
println!("hello!");
|
||||||
|
Ok(None)
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
use crate::{token::Prim, parser::data::{Declr}, vmrt::Data, builtin::BuiltinFun};
|
||||||
|
|
||||||
|
pub fn int_to_rat(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
match args [0] {
|
||||||
|
Data::Int(val) => Ok(Some(Data::Rat(val as f64))),
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rat_to_int(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
match args[0] {
|
||||||
|
Data::Rat(val) => Ok(Some(Data::Int(val as i64))),
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn str_to_int(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
match &args[0] {
|
||||||
|
Data::Str(val) => Ok(Some(Data::Int(val.parse().unwrap_or(0)))),
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn str_to_rat(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
match &args[0] {
|
||||||
|
Data::Str(val) => Ok(Some(Data::Rat(val.parse().unwrap_or(0.0)))),
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_module_funs<'a>() -> Vec<crate::builtin::BuiltinFun> {
|
||||||
|
vec![
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("to_rat", vec![("x", Prim::Int)], Some(Prim::Rat)),
|
||||||
|
func: &int_to_rat
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("to_int", vec![("x", Prim::Rat)], Some(Prim::Int)),
|
||||||
|
func: &rat_to_int
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("parse_int", vec![("text", Prim::Str)], Some(Prim::Int)),
|
||||||
|
func: &str_to_int
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("parse_rat", vec![("text", Prim::Str)], Some(Prim::Rat)),
|
||||||
|
func: &str_to_rat
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
use crate::{token::Prim, parser::data::{Declr}, vmrt::Data, builtin::BuiltinFun};
|
||||||
|
|
||||||
|
pub fn print(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
let text = args[0].to_str()?;
|
||||||
|
print!("{}", text);
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn println(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
let text = args[0].to_str()?;
|
||||||
|
println!("{}", text);
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_module_funs<'a>() -> Vec<crate::builtin::BuiltinFun> {
|
||||||
|
vec![
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("print", vec![("text", Prim::Str)], None),
|
||||||
|
func: &print
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("println", vec![("text", Prim::Str)], None),
|
||||||
|
func: &println
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
use crate::{token::Prim, parser::data::{Declr}, vmrt::Data, builtin::BuiltinFun};
|
||||||
|
|
||||||
|
pub fn cos(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
Ok(Some(Data::Rat(args[0].to_float()?.cos())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sin(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
Ok(Some(Data::Rat(args[0].to_float()?.sin())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tan(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
Ok(Some(Data::Rat(args[0].to_float()?.tan())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ln(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
Ok(Some(Data::Rat(args[0].to_float()?.ln())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sqrt(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
Ok(Some(Data::Rat(args[0].to_float()?.sqrt())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pow(args: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
let x = args[0].to_float()?;
|
||||||
|
let y = args[1].to_float()?;
|
||||||
|
|
||||||
|
Ok(Some(Data::Rat(y.powf(x))))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_module_funs<'a>() -> Vec<crate::builtin::BuiltinFun> {
|
||||||
|
vec![
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("cos", vec![("x", Prim::Int)], Some(Prim::Rat)),
|
||||||
|
func: &cos
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("pow", vec![("x", Prim::Rat), ("y", Prim::Rat)], Some(Prim::Rat)),
|
||||||
|
func: &pow
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("sin", vec![("x", Prim::Int)], Some(Prim::Rat)),
|
||||||
|
func: &sin
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("tan", vec![("x", Prim::Int)], Some(Prim::Rat)),
|
||||||
|
func: &tan
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("ln", vec![("x", Prim::Int)], Some(Prim::Rat)),
|
||||||
|
func: &ln
|
||||||
|
},
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("sqrt", vec![("x", Prim::Int)], Some(Prim::Rat)),
|
||||||
|
func: &sqrt
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
pub mod conv;
|
||||||
|
pub mod math;
|
||||||
|
pub mod io;
|
||||||
|
pub mod os;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub enum Module {
|
||||||
|
Conv,
|
||||||
|
Math,
|
||||||
|
IO,
|
||||||
|
OS,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Module {
|
||||||
|
|
||||||
|
pub fn from_list(text: &str) -> Vec<Module> {
|
||||||
|
let mut vec = vec![];
|
||||||
|
|
||||||
|
for word in text.split(',') {
|
||||||
|
match word.trim() {
|
||||||
|
"conv" => vec.push(Module::Conv),
|
||||||
|
"math" => vec.push(Module::Math),
|
||||||
|
"io" => vec.push(Module::IO),
|
||||||
|
"os" => vec.push(Module::OS),
|
||||||
|
_ => crate::message(crate::token::MessageType::Warning, format!("unknown module: `{}`", word))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_submodules<'a>(modules: &[Module]) -> Vec<super::BuiltinFun> {
|
||||||
|
let mut funs = vec![];
|
||||||
|
|
||||||
|
for module in modules {
|
||||||
|
match module {
|
||||||
|
Module::Conv => funs.append(&mut conv::get_module_funs()),
|
||||||
|
Module::Math => funs.append(&mut math::get_module_funs()),
|
||||||
|
Module::IO => funs.append(&mut io::get_module_funs()),
|
||||||
|
Module::OS => funs.append(&mut os::get_module_funs()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
funs
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use crate::{token::Prim, parser::data::{Declr}, vmrt::Data, builtin::BuiltinFun};
|
||||||
|
|
||||||
|
pub fn get_os(_: &[Data]) -> Result<Option<Data>, ()> {
|
||||||
|
|
||||||
|
if cfg!(windows) {
|
||||||
|
return Ok(Some(Data::Str(String::from("Windows"))))
|
||||||
|
} else if cfg!(unix) {
|
||||||
|
return Ok(Some(Data::Str(String::from("UNIX"))))
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_module_funs<'a>() -> Vec<crate::builtin::BuiltinFun> {
|
||||||
|
vec![
|
||||||
|
BuiltinFun {
|
||||||
|
declr: Declr::generate_builtin("get_os", vec![], Some(Prim::Str)),
|
||||||
|
func: &get_os
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
use std::{collections::VecDeque};
|
||||||
|
|
||||||
|
use crate::{token::{Token}, builtin::modules::Module};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct LangSpecs {
|
||||||
|
/// builtin modules for extra builtin functions
|
||||||
|
builtin_features: Vec<crate::builtin::modules::Module>,
|
||||||
|
lang_version: u32,
|
||||||
|
authors: Vec<String>,
|
||||||
|
embedded_files: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LangSpecs {
|
||||||
|
|
||||||
|
pub fn features(&self) -> &[crate::builtin::modules::Module] {
|
||||||
|
&self.builtin_features
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_directives(tokens: &mut VecDeque<Token>) -> LangSpecs {
|
||||||
|
let mut specs = LangSpecs::default();
|
||||||
|
|
||||||
|
for token in tokens.iter() {
|
||||||
|
match token {
|
||||||
|
Token::CompilerDirective(text, _) => parse_directive(text, &mut specs),
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove compiler directives from source
|
||||||
|
tokens.retain(|token| match token {
|
||||||
|
Token::CompilerDirective(_, _) => false,
|
||||||
|
_ => true
|
||||||
|
});
|
||||||
|
|
||||||
|
specs
|
||||||
|
}
|
||||||
|
|
||||||
|
static DIRECTIVE_REGEX_SRC: &'static str = concat!(
|
||||||
|
r"@feature\(((?:\s*[\w]+\s*,?)*)\)",
|
||||||
|
r"|@version\(\s*([0-9]{3})\s*\)",
|
||||||
|
r"|@author\((.*)\)",
|
||||||
|
r"|@embed\((.*)\)"
|
||||||
|
);
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref DIRECTIVE_REGEX: regex::Regex = regex::Regex::new(DIRECTIVE_REGEX_SRC).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_list(text: &str) -> Vec<String> {
|
||||||
|
let mut vec = vec![];
|
||||||
|
|
||||||
|
for word in text.split(',') {
|
||||||
|
vec.push(String::from(word.trim()))
|
||||||
|
}
|
||||||
|
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_directive(text: &str, specs: &mut LangSpecs) {
|
||||||
|
|
||||||
|
for cap in DIRECTIVE_REGEX.captures_iter(text) {
|
||||||
|
let mut enumerator = cap.iter().enumerate();
|
||||||
|
loop {
|
||||||
|
let next = enumerator.next();
|
||||||
|
if next.is_none() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (i, group) = next.unwrap();
|
||||||
|
|
||||||
|
// ignore first group as its the entire match,
|
||||||
|
// as well as the 1st group (= comments)
|
||||||
|
if i < 1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mat) = group {
|
||||||
|
match i {
|
||||||
|
1 => {
|
||||||
|
specs.builtin_features.append(&mut Module::from_list(mat.as_str()));
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
2 => {
|
||||||
|
specs.lang_version = mat.as_str().parse().unwrap();
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
3 => {
|
||||||
|
specs.authors.push(String::from(mat.as_str()));
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
4 => {
|
||||||
|
specs.embedded_files.append(&mut from_list(mat.as_str()));
|
||||||
|
crate::message(crate::token::MessageType::Warning, "Embed directive not working at current state");
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
_ => crate::message(crate::token::MessageType::Warning, format!("unknown directive: `{}`", text)),
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::message(crate::token::MessageType::Warning, format!("unknown directive: `{}`", text));
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
/// SENI - Standard Edition Native Interface (for rust)
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
use std::{fs};
|
||||||
|
|
||||||
|
pub struct CodeSrc {
|
||||||
|
_path: String,
|
||||||
|
src: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodeSrc {
|
||||||
|
|
||||||
|
pub fn new(path: &String) -> Result<CodeSrc, String> {
|
||||||
|
Ok(Self {
|
||||||
|
_path: path.to_owned(),
|
||||||
|
src: Self::read_code(path)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_code(path: &String) -> Result<String, String> {
|
||||||
|
let result = fs::read_to_string(path);
|
||||||
|
|
||||||
|
// read the source
|
||||||
|
if let Ok(src) = result {
|
||||||
|
return Ok(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(format!("unable to fetch source code from {}: {}", path, result.err().unwrap()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn code(&self) -> &String {
|
||||||
|
&self.src
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
@feature(io)
|
||||||
|
@version(100)
|
||||||
|
@author(Sven Vogel)
|
||||||
|
|
||||||
|
// recursion!
|
||||||
|
fac(x:int) = int {
|
||||||
|
despite x != 1 {
|
||||||
|
yield 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield fac(x - 1) * x
|
||||||
|
}
|
||||||
|
|
||||||
|
main() = int {
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
loop {
|
||||||
|
|
||||||
|
until x > 9 {
|
||||||
|
despite x != 5 {
|
||||||
|
x = x + 1
|
||||||
|
cont
|
||||||
|
}
|
||||||
|
|
||||||
|
println(""..x);
|
||||||
|
x = x + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
println(""..fract(456.3928));
|
||||||
|
|
||||||
|
yield 0
|
||||||
|
}
|
Loading…
Reference in New Issue