changes
This commit is contained in:
parent
2b116296bc
commit
d0eedfd810
33 changed files with 159 additions and 142 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -55,9 +55,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.20"
|
version = "4.5.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
|
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
@ -65,9 +65,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.20"
|
version = "4.5.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
|
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
|
@ -87,9 +87,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
members = ["talc-lang", "talc-bin", "talc-std", "talc-macros"]
|
members = ["talc-lang", "talc-bin", "talc-std", "talc-macros"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
|
|
||||||
[profile.release-opt]
|
[profile.release-opt]
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
## installation
|
## installation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cargo install --profile release-lto --path talc-bin
|
cargo install --profile release-opt --path talc-bin
|
||||||
```
|
```
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustyline::{
|
||||||
use talc_lang::{
|
use talc_lang::{
|
||||||
lstring::LStr,
|
lstring::LStr,
|
||||||
parser::{Lexer, Pos, Span, TokenKind},
|
parser::{Lexer, Pos, Span, TokenKind},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TalcHelper {
|
pub struct TalcHelper {
|
||||||
|
|
|
@ -3,10 +3,11 @@ use std::{path::PathBuf, process::ExitCode, rc::Rc};
|
||||||
use talc_lang::{
|
use talc_lang::{
|
||||||
compiler::compile,
|
compiler::compile,
|
||||||
lstring::LString,
|
lstring::LString,
|
||||||
optimize, parser, serial,
|
optimize::optimize,
|
||||||
|
parser, serial,
|
||||||
symbol::Symbol,
|
symbol::Symbol,
|
||||||
value::{function::disasm_recursive, Value},
|
value::{function::disasm_recursive, Value},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod helper;
|
mod helper;
|
||||||
|
|
|
@ -8,10 +8,12 @@ use rustyline::{
|
||||||
};
|
};
|
||||||
use talc_lang::{
|
use talc_lang::{
|
||||||
compiler::compile_repl,
|
compiler::compile_repl,
|
||||||
lstr, optimize, parser,
|
lstr,
|
||||||
|
optimize::optimize,
|
||||||
|
parser,
|
||||||
symbol::{symbol, Symbol},
|
symbol::{symbol, Symbol},
|
||||||
value::{function::disasm_recursive, Value},
|
value::{function::disasm_recursive, Value},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{helper::TalcHelper, Args};
|
use crate::{helper::TalcHelper, Args};
|
||||||
|
@ -117,17 +119,14 @@ fn exec_line(
|
||||||
eprintln!("{}", ex);
|
eprintln!("{}", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (f, g) = match compile_repl(&ex, globals) {
|
let func = match compile_repl(&ex, globals) {
|
||||||
Ok(pair) => pair,
|
Ok(f) => Rc::new(f),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("{}Error:{} {e}", c.error, c.reset);
|
eprintln!("{}Error:{} {e}", c.error, c.reset);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*globals = g;
|
|
||||||
let func = Rc::new(f);
|
|
||||||
|
|
||||||
if args.disasm {
|
if args.disasm {
|
||||||
if let Err(e) = disasm_recursive(&func, &mut std::io::stderr()) {
|
if let Err(e) = disasm_recursive(&func, &mut std::io::stderr()) {
|
||||||
eprintln!("{}Error:{} {e}", c.error, c.reset);
|
eprintln!("{}Error:{} {e}", c.error, c.reset);
|
||||||
|
|
|
@ -9,5 +9,3 @@ num-rational = { version = "0.4", default-features = false, features = [] }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
unicode-ident = "1.0"
|
unicode-ident = "1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::rc::Rc;
|
||||||
use crate::chunk::{Arg24, Catch, Chunk, Instruction as I};
|
use crate::chunk::{Arg24, Catch, Chunk, Instruction as I};
|
||||||
use crate::parser::ast::{BinaryOp, CatchBlock, Expr, ExprKind, LValue, LValueKind};
|
use crate::parser::ast::{BinaryOp, CatchBlock, Expr, ExprKind, LValue, LValueKind};
|
||||||
use crate::parser::Pos;
|
use crate::parser::Pos;
|
||||||
use crate::symbol::{Symbol, SYM_SELF};
|
use crate::symbol::{Symbol, SYM_REPL, SYM_SELF};
|
||||||
use crate::throw;
|
use crate::throw;
|
||||||
use crate::value::function::{FuncAttrs, Function};
|
use crate::value::function::{FuncAttrs, Function};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
@ -39,18 +39,12 @@ enum ResolveOutcome {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum VarKind {
|
enum VarKind {
|
||||||
Local(usize),
|
Local(usize),
|
||||||
Closed(usize),
|
Closed(usize),
|
||||||
Global,
|
Global,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Var {
|
|
||||||
name: Symbol,
|
|
||||||
kind: VarKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
enum CompilerMode {
|
enum CompilerMode {
|
||||||
Function,
|
Function,
|
||||||
|
@ -72,8 +66,8 @@ struct Compiler<'a> {
|
||||||
chunk: Chunk,
|
chunk: Chunk,
|
||||||
attrs: FuncAttrs,
|
attrs: FuncAttrs,
|
||||||
// variables
|
// variables
|
||||||
scope: HashMap<Symbol, Var>,
|
scope: HashMap<Symbol, VarKind>,
|
||||||
shadowed: Vec<(Symbol, Option<Var>)>,
|
shadowed: Vec<(Symbol, Option<VarKind>)>,
|
||||||
closes: Vec<(Symbol, usize)>,
|
closes: Vec<(Symbol, usize)>,
|
||||||
local_count: usize,
|
local_count: usize,
|
||||||
// break and continue
|
// break and continue
|
||||||
|
@ -87,22 +81,16 @@ pub fn compile(expr: &Expr, name: Option<Symbol>) -> Result<Function> {
|
||||||
Ok(comp.finish())
|
Ok(comp.finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_repl(expr: &Expr, globals: &[Symbol]) -> Result<(Function, Vec<Symbol>)> {
|
pub fn compile_repl(expr: &Expr, globals: &mut Vec<Symbol>) -> Result<Function> {
|
||||||
let mut comp = Compiler::new_repl(globals);
|
let mut comp = Compiler::new_repl(globals);
|
||||||
comp.expr(expr)?;
|
comp.expr(expr)?;
|
||||||
Ok(comp.finish_repl())
|
Ok(comp.finish_repl(globals))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for Compiler<'a> {
|
impl<'a> Default for Compiler<'a> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut scope = HashMap::new();
|
let mut scope = HashMap::new();
|
||||||
scope.insert(
|
scope.insert(*SYM_SELF, VarKind::Local(0));
|
||||||
*SYM_SELF,
|
|
||||||
Var {
|
|
||||||
name: *SYM_SELF,
|
|
||||||
kind: VarKind::Local(0),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Self {
|
Self {
|
||||||
mode: CompilerMode::Function,
|
mode: CompilerMode::Function,
|
||||||
parent: None,
|
parent: None,
|
||||||
|
@ -124,7 +112,7 @@ impl<'a> Compiler<'a> {
|
||||||
mode: CompilerMode::Repl,
|
mode: CompilerMode::Repl,
|
||||||
attrs: FuncAttrs {
|
attrs: FuncAttrs {
|
||||||
arity: 0,
|
arity: 0,
|
||||||
name: Some(Symbol::get("<repl>")),
|
name: Some(*SYM_REPL),
|
||||||
},
|
},
|
||||||
..Self::default()
|
..Self::default()
|
||||||
};
|
};
|
||||||
|
@ -162,30 +150,29 @@ impl<'a> Compiler<'a> {
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(mut self) -> Function {
|
fn finish(mut self) -> Function {
|
||||||
self.emit(I::Return);
|
self.emit(I::Return);
|
||||||
Function::new(Rc::new(self.chunk), self.attrs, self.closes.len())
|
Function::new(Rc::new(self.chunk), self.attrs, self.closes.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish_inner(mut self) -> (Function, Vec<(Symbol, usize)>) {
|
fn finish_inner(mut self) -> (Function, Vec<(Symbol, usize)>) {
|
||||||
self.emit(I::Return);
|
self.emit(I::Return);
|
||||||
// TODO closure
|
|
||||||
(
|
(
|
||||||
Function::new(Rc::new(self.chunk), self.attrs, self.closes.len()),
|
Function::new(Rc::new(self.chunk), self.attrs, self.closes.len()),
|
||||||
self.closes,
|
self.closes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish_repl(mut self) -> (Function, Vec<Symbol>) {
|
fn finish_repl(mut self, globals: &mut Vec<Symbol>) -> Function {
|
||||||
self.emit(I::Return);
|
self.emit(I::Return);
|
||||||
(
|
|
||||||
// TODO closure
|
globals.clear();
|
||||||
Function::new(Rc::new(self.chunk), self.attrs, self.closes.len()),
|
for (name, kind) in self.scope.iter() {
|
||||||
self.scope
|
if *kind == VarKind::Global {
|
||||||
.into_iter()
|
globals.push(*name);
|
||||||
.filter_map(|(_, v)| (v.kind == VarKind::Global).then_some(v.name))
|
}
|
||||||
.collect(),
|
}
|
||||||
)
|
Function::new(Rc::new(self.chunk), self.attrs, self.closes.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -306,7 +293,7 @@ impl<'a> Compiler<'a> {
|
||||||
let (name, var) = self.shadowed.pop().expect("scope bad");
|
let (name, var) = self.shadowed.pop().expect("scope bad");
|
||||||
|
|
||||||
if let Some(in_var) = self.scope.get(&name) {
|
if let Some(in_var) = self.scope.get(&name) {
|
||||||
if in_var.kind != VarKind::Global {
|
if *in_var != VarKind::Global {
|
||||||
locals += 1;
|
locals += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,8 +316,8 @@ impl<'a> Compiler<'a> {
|
||||||
//
|
//
|
||||||
|
|
||||||
fn resolve_name(&self, name: Symbol) -> ResolveOutcome {
|
fn resolve_name(&self, name: Symbol) -> ResolveOutcome {
|
||||||
if let Some(v) = self.scope.get(&name) {
|
if let Some(kind) = self.scope.get(&name) {
|
||||||
return ResolveOutcome::Var(v.kind)
|
return ResolveOutcome::Var(*kind)
|
||||||
}
|
}
|
||||||
let Some(parent) = self.parent else {
|
let Some(parent) = self.parent else {
|
||||||
return ResolveOutcome::None
|
return ResolveOutcome::None
|
||||||
|
@ -369,10 +356,7 @@ impl<'a> Compiler<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declare_local(&mut self, name: Symbol) -> usize {
|
fn declare_local(&mut self, name: Symbol) -> usize {
|
||||||
let local = Var {
|
let local = VarKind::Local(self.local_count);
|
||||||
name,
|
|
||||||
kind: VarKind::Local(self.local_count),
|
|
||||||
};
|
|
||||||
self.local_count += 1;
|
self.local_count += 1;
|
||||||
let shadowed = self.scope.insert(name, local);
|
let shadowed = self.scope.insert(name, local);
|
||||||
self.shadowed.push((name, shadowed));
|
self.shadowed.push((name, shadowed));
|
||||||
|
@ -391,11 +375,7 @@ impl<'a> Compiler<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declare_global(&mut self, name: Symbol) {
|
fn declare_global(&mut self, name: Symbol) {
|
||||||
let global = Var {
|
let shadowed = self.scope.insert(name, VarKind::Global);
|
||||||
name,
|
|
||||||
kind: VarKind::Global,
|
|
||||||
};
|
|
||||||
let shadowed = self.scope.insert(name, global);
|
|
||||||
self.shadowed.push((name, shadowed));
|
self.shadowed.push((name, shadowed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,9 +732,7 @@ impl<'a> Compiler<'a> {
|
||||||
match self.resolve_name(name) {
|
match self.resolve_name(name) {
|
||||||
ResolveOutcome::Var(VarKind::Local(n)) => {
|
ResolveOutcome::Var(VarKind::Local(n)) => {
|
||||||
self.emit(I::CloseOver(Arg24::from_usize(n)));
|
self.emit(I::CloseOver(Arg24::from_usize(n)));
|
||||||
self.scope.entry(name).and_modify(|v| {
|
self.scope.insert(name, VarKind::Closed(n));
|
||||||
v.kind = VarKind::Closed(n);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
ResolveOutcome::Var(VarKind::Closed(n)) => {
|
ResolveOutcome::Var(VarKind::Closed(n)) => {
|
||||||
self.emit(I::LoadLocal(Arg24::from_usize(n)));
|
self.emit(I::LoadLocal(Arg24::from_usize(n)));
|
||||||
|
|
|
@ -8,12 +8,9 @@ pub mod chunk;
|
||||||
pub mod compiler;
|
pub mod compiler;
|
||||||
pub mod exception;
|
pub mod exception;
|
||||||
pub mod lstring;
|
pub mod lstring;
|
||||||
mod optimize;
|
pub mod optimize;
|
||||||
pub use optimize::optimize;
|
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
pub mod symbol;
|
pub mod symbol;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
pub mod vm;
|
||||||
mod vm;
|
|
||||||
pub use vm::Vm;
|
|
||||||
|
|
|
@ -27,12 +27,12 @@ struct OptState {
|
||||||
|
|
||||||
impl OptState {
|
impl OptState {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn empty() -> Self {
|
const fn empty() -> Self {
|
||||||
Self { ret: false }
|
Self { ret: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn ret(ret: bool) -> Self {
|
const fn ret(ret: bool) -> Self {
|
||||||
Self { ret }
|
Self { ret }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ fn optimize_ex_with(expr: &mut Expr, state: OptState) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn optimize_lv(e: &mut LValue) {
|
fn optimize_lv(e: &mut LValue) {
|
||||||
match &mut e.kind {
|
match &mut e.kind {
|
||||||
LValueKind::Ident(_) => (),
|
LValueKind::Ident(_) => (),
|
||||||
LValueKind::Index(l, r) => {
|
LValueKind::Index(l, r) => {
|
||||||
|
@ -224,6 +224,6 @@ pub fn optimize_lv(e: &mut LValue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn optimize_cb(e: &mut CatchBlock) {
|
fn optimize_cb(e: &mut CatchBlock) {
|
||||||
optimize_ex(&mut e.body);
|
optimize_ex(&mut e.body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub enum BinaryOp {
|
||||||
pub enum UnaryOp {
|
pub enum UnaryOp {
|
||||||
Neg,
|
Neg,
|
||||||
Not,
|
Not,
|
||||||
|
BitNot,
|
||||||
RangeEndless,
|
RangeEndless,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub enum TokenKind {
|
||||||
Eof,
|
Eof,
|
||||||
LineSeparator,
|
LineSeparator,
|
||||||
|
|
||||||
Bang,
|
Tilde,
|
||||||
BangEqual,
|
BangEqual,
|
||||||
HashAmper,
|
HashAmper,
|
||||||
HashAmperEqual,
|
HashAmperEqual,
|
||||||
|
@ -42,7 +42,6 @@ pub enum TokenKind {
|
||||||
SlashSlash,
|
SlashSlash,
|
||||||
SlashSlashEqual,
|
SlashSlashEqual,
|
||||||
SlashEqual,
|
SlashEqual,
|
||||||
Colon,
|
|
||||||
Less,
|
Less,
|
||||||
LessLess,
|
LessLess,
|
||||||
LessLessEqual,
|
LessLessEqual,
|
||||||
|
@ -101,7 +100,7 @@ impl TokenKind {
|
||||||
match self {
|
match self {
|
||||||
K::Eof => "end of file",
|
K::Eof => "end of file",
|
||||||
K::LineSeparator => "line separator",
|
K::LineSeparator => "line separator",
|
||||||
K::Bang => "'!'",
|
K::Tilde => "'~'",
|
||||||
K::BangEqual => "'!='",
|
K::BangEqual => "'!='",
|
||||||
K::HashAmper => "'#&'",
|
K::HashAmper => "'#&'",
|
||||||
K::HashAmperEqual => "'#&='",
|
K::HashAmperEqual => "'#&='",
|
||||||
|
@ -123,7 +122,7 @@ impl TokenKind {
|
||||||
K::Comma => "','",
|
K::Comma => "','",
|
||||||
K::Minus => "'-'",
|
K::Minus => "'-'",
|
||||||
K::MinusEqual => "'-='",
|
K::MinusEqual => "'-='",
|
||||||
K::Arrow => "'=>'",
|
K::Arrow => "'->'",
|
||||||
K::Dot => "'.'",
|
K::Dot => "'.'",
|
||||||
K::DotDot => "'..'",
|
K::DotDot => "'..'",
|
||||||
K::DotDotStar => "'..*'",
|
K::DotDotStar => "'..*'",
|
||||||
|
@ -132,7 +131,6 @@ impl TokenKind {
|
||||||
K::SlashSlash => "'//'",
|
K::SlashSlash => "'//'",
|
||||||
K::SlashSlashEqual => "'//='",
|
K::SlashSlashEqual => "'//='",
|
||||||
K::SlashEqual => "'/='",
|
K::SlashEqual => "'/='",
|
||||||
K::Colon => "':'",
|
|
||||||
K::Less => "'<'",
|
K::Less => "'<'",
|
||||||
K::LessLess => "'<<'",
|
K::LessLess => "'<<'",
|
||||||
K::LessLessEqual => "'<<='",
|
K::LessLessEqual => "'<<='",
|
||||||
|
@ -526,11 +524,12 @@ impl<'s> Lexer<'s> {
|
||||||
'!' => self.line_comment(),
|
'!' => self.line_comment(),
|
||||||
_ => self.unexpected(),
|
_ => self.unexpected(),
|
||||||
},
|
},
|
||||||
// lists
|
'~' => self.and_emit(K::Tilde),
|
||||||
'!' => match self.and_peek()? {
|
'!' => match self.and_peek()? {
|
||||||
'=' => self.and_emit(K::BangEqual),
|
'=' => self.and_emit(K::BangEqual),
|
||||||
_ => self.emit(K::Bang),
|
_ => self.unexpected(),
|
||||||
},
|
},
|
||||||
|
// lists
|
||||||
'&' => match self.and_peek()? {
|
'&' => match self.and_peek()? {
|
||||||
'=' => self.and_emit(K::AmperEqual),
|
'=' => self.and_emit(K::AmperEqual),
|
||||||
_ => self.emit(K::Amper),
|
_ => self.emit(K::Amper),
|
||||||
|
@ -569,7 +568,7 @@ impl<'s> Lexer<'s> {
|
||||||
c if is_xid_start(c) || c == '_' || c == '"' || c == '\'' => {
|
c if is_xid_start(c) || c == '_' || c == '"' || c == '\'' => {
|
||||||
self.next_symbol()
|
self.next_symbol()
|
||||||
}
|
}
|
||||||
_ => self.emit(K::Colon),
|
_ => self.unexpected(),
|
||||||
},
|
},
|
||||||
'0'..='9' => self.next_number(),
|
'0'..='9' => self.next_number(),
|
||||||
c if c == '_' || is_xid_start(c) => self.next_ident(),
|
c if c == '_' || is_xid_start(c) => self.next_ident(),
|
||||||
|
|
|
@ -54,7 +54,7 @@ macro_rules! throw {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenKind {
|
impl TokenKind {
|
||||||
pub fn assign_op(self) -> Option<Option<BinaryOp>> {
|
fn assign_op(self) -> Option<Option<BinaryOp>> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
T::PlusPlusEqual => Some(BinaryOp::Concat),
|
T::PlusPlusEqual => Some(BinaryOp::Concat),
|
||||||
T::AmperEqual => Some(BinaryOp::Append),
|
T::AmperEqual => Some(BinaryOp::Append),
|
||||||
|
@ -75,7 +75,7 @@ impl TokenKind {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn binary_op(self) -> Option<BinaryOp> {
|
fn binary_op(self) -> Option<BinaryOp> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
T::EqualEqual => BinaryOp::Eq,
|
T::EqualEqual => BinaryOp::Eq,
|
||||||
T::BangEqual => BinaryOp::Ne,
|
T::BangEqual => BinaryOp::Ne,
|
||||||
|
@ -103,15 +103,16 @@ impl TokenKind {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unary_op(self) -> Option<UnaryOp> {
|
fn unary_op(self) -> Option<UnaryOp> {
|
||||||
match self {
|
match self {
|
||||||
T::Minus => Some(UnaryOp::Neg),
|
T::Minus => Some(UnaryOp::Neg),
|
||||||
T::Not => Some(UnaryOp::Not),
|
T::Not => Some(UnaryOp::Not),
|
||||||
|
T::Tilde => Some(UnaryOp::BitNot),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn postfix_unary_op(self) -> Option<UnaryOp> {
|
fn postfix_unary_op(self) -> Option<UnaryOp> {
|
||||||
match self {
|
match self {
|
||||||
T::DotDotStar => Some(UnaryOp::RangeEndless),
|
T::DotDotStar => Some(UnaryOp::RangeEndless),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -120,17 +121,17 @@ impl TokenKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnaryOp {
|
impl UnaryOp {
|
||||||
pub fn precedence(self) -> u8 {
|
fn precedence(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
UnaryOp::Not => 0,
|
UnaryOp::Not => 0,
|
||||||
UnaryOp::RangeEndless => 40,
|
UnaryOp::RangeEndless => 40,
|
||||||
UnaryOp::Neg => 110,
|
UnaryOp::Neg | UnaryOp::BitNot => 110,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinaryOp {
|
impl BinaryOp {
|
||||||
pub fn precedence(self) -> (u8, u8) {
|
fn precedence(self) -> (u8, u8) {
|
||||||
match self {
|
match self {
|
||||||
BinaryOp::Eq
|
BinaryOp::Eq
|
||||||
| BinaryOp::Ne
|
| BinaryOp::Ne
|
||||||
|
@ -166,8 +167,8 @@ impl TokenKind {
|
||||||
| T::Break | T::Var
|
| T::Break | T::Var
|
||||||
| T::Global | T::Fn
|
| T::Global | T::Fn
|
||||||
| T::Not | T::Backslash
|
| T::Not | T::Backslash
|
||||||
| T::Colon | T::Minus
|
| T::Amper | T::Minus
|
||||||
| T::Identifier
|
| T::Tilde | T::Identifier
|
||||||
| T::LParen | T::LBrack
|
| T::LParen | T::LBrack
|
||||||
| T::LBrace | T::Dollar
|
| T::LBrace | T::Dollar
|
||||||
| T::Do | T::If
|
| T::Do | T::If
|
||||||
|
@ -494,7 +495,7 @@ impl<'s> Parser<'s> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_lambda(&mut self) -> Result<Expr> {
|
fn parse_lambda(&mut self) -> Result<Expr> {
|
||||||
let tok = try_next!(self, T::Backslash | T::Colon);
|
let tok = try_next!(self, T::Backslash | T::Amper);
|
||||||
match tok {
|
match tok {
|
||||||
Some(Token {
|
Some(Token {
|
||||||
kind: T::Backslash,
|
kind: T::Backslash,
|
||||||
|
@ -502,13 +503,13 @@ impl<'s> Parser<'s> {
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let args = self.parse_ident_list()?;
|
let args = self.parse_ident_list()?;
|
||||||
expect!(self, T::Arrow);
|
expect!(self, T::Dot);
|
||||||
let body = self.parse_lambda()?;
|
let body = self.parse_lambda()?;
|
||||||
let body_span = body.span;
|
let body_span = body.span;
|
||||||
Ok(E::Lambda(args, b(body)).span(span + body_span))
|
Ok(E::Lambda(args, b(body)).span(span + body_span))
|
||||||
}
|
}
|
||||||
Some(Token {
|
Some(Token {
|
||||||
kind: T::Colon,
|
kind: T::Amper,
|
||||||
span,
|
span,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct SymbolTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
pub static ref SYM_REPL: Symbol = symbol!("<repl>");
|
||||||
pub static ref SYM_SELF: Symbol = symbol!(self);
|
pub static ref SYM_SELF: Symbol = symbol!(self);
|
||||||
pub static ref SYM_DOLLAR_SIGN: Symbol = symbol!("$");
|
pub static ref SYM_DOLLAR_SIGN: Symbol = symbol!("$");
|
||||||
pub static ref SYM_NIL: Symbol = symbol!(nil);
|
pub static ref SYM_NIL: Symbol = symbol!(nil);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use crate::{chunk::Chunk, exception::Result, symbol::Symbol, Vm};
|
use crate::{chunk::Chunk, exception::Result, symbol::Symbol, vm::Vm};
|
||||||
|
|
||||||
use super::{CellValue, Value};
|
use super::{CellValue, Value};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@ use crate::{
|
||||||
exception::{throw, Result},
|
exception::{throw, Result},
|
||||||
symbol::{symbol, SYM_END_ITERATION, SYM_INDEX_ERROR, SYM_TYPE_ERROR},
|
symbol::{symbol, SYM_END_ITERATION, SYM_INDEX_ERROR, SYM_TYPE_ERROR},
|
||||||
value::function::NativeFunc,
|
value::function::NativeFunc,
|
||||||
vmcalliter, Vm,
|
vm::Vm,
|
||||||
|
vmcalliter,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{range::RangeType, Value};
|
use super::{range::RangeType, Value};
|
||||||
|
@ -126,7 +127,11 @@ impl Value {
|
||||||
(V::Table(t), i) if i.hashable() => {
|
(V::Table(t), i) if i.hashable() => {
|
||||||
let mut t = t.borrow_mut();
|
let mut t = t.borrow_mut();
|
||||||
let i = i.try_into()?;
|
let i = i.try_into()?;
|
||||||
t.insert(i, val);
|
if val == Value::Nil {
|
||||||
|
t.remove(&i);
|
||||||
|
} else {
|
||||||
|
t.insert(i, val);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
(V::List(t), V::Range(r)) => {
|
(V::List(t), V::Range(r)) => {
|
||||||
|
|
|
@ -169,6 +169,9 @@ impl Value {
|
||||||
if recur.contains(&(t.as_ptr() as _)) {
|
if recur.contains(&(t.as_ptr() as _)) {
|
||||||
return w.write_all(b"{...}")
|
return w.write_all(b"{...}")
|
||||||
}
|
}
|
||||||
|
if t.borrow().len() == 0 {
|
||||||
|
return w.write_all(b"{}")
|
||||||
|
}
|
||||||
w.write_all(b"{ ")?;
|
w.write_all(b"{ ")?;
|
||||||
recur.push(t.as_ptr() as _);
|
recur.push(t.as_ptr() as _);
|
||||||
for (i, (k, v)) in t.borrow().iter().enumerate() {
|
for (i, (k, v)) in t.borrow().iter().enumerate() {
|
||||||
|
@ -176,7 +179,7 @@ impl Value {
|
||||||
w.write_all(b", ")?;
|
w.write_all(b", ")?;
|
||||||
}
|
}
|
||||||
k.0.write_table_key_repr(w, recur)?;
|
k.0.write_table_key_repr(w, recur)?;
|
||||||
w.write_all(b" = ")?;
|
w.write_all(b"=")?;
|
||||||
v.write_to_lstring(w, true, recur)?;
|
v.write_to_lstring(w, true, recur)?;
|
||||||
}
|
}
|
||||||
recur.pop();
|
recur.pop();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Shl, Shr, Sub},
|
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Shl, Shr, Sub},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
lstring::LString,
|
lstring::LString,
|
||||||
symbol::{symbol, SYM_END_ITERATION, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{symbol, SYM_END_ITERATION, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
value::range::RangeType,
|
value::range::RangeType,
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -388,7 +388,9 @@ impl Shl<Value> for Value {
|
||||||
fn shl(self, rhs: Value) -> Self::Output {
|
fn shl(self, rhs: Value) -> Self::Output {
|
||||||
use Value as V;
|
use Value as V;
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(V::Int(a), V::Int(b)) => Ok(Value::Int(((a as u64) << b as u64) as i64)),
|
(V::Int(a), V::Int(b)) => {
|
||||||
|
Ok(Value::Int((a as u64).wrapping_shl(b as u32) as i64))
|
||||||
|
}
|
||||||
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} left by {r:#}"),
|
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} left by {r:#}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,7 +402,9 @@ impl Shr<Value> for Value {
|
||||||
fn shr(self, rhs: Value) -> Self::Output {
|
fn shr(self, rhs: Value) -> Self::Output {
|
||||||
use Value as V;
|
use Value as V;
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(V::Int(a), V::Int(b)) => Ok(Value::Int((a as u64 >> b as u64) as i64)),
|
(V::Int(a), V::Int(b)) => {
|
||||||
|
Ok(Value::Int((a as u64).wrapping_shr(b as u32) as i64))
|
||||||
|
}
|
||||||
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} right by {r:#}"),
|
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} right by {r:#}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,7 +417,7 @@ impl BitAnd<Value> for Value {
|
||||||
use Value as V;
|
use Value as V;
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(V::Int(a), V::Int(b)) => Ok(Value::Int(a & b)),
|
(V::Int(a), V::Int(b)) => Ok(Value::Int(a & b)),
|
||||||
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} right by {r:#}"),
|
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot bitwise and {l:#} and {r:#}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,7 +429,7 @@ impl BitXor<Value> for Value {
|
||||||
use Value as V;
|
use Value as V;
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(V::Int(a), V::Int(b)) => Ok(Value::Int(a ^ b)),
|
(V::Int(a), V::Int(b)) => Ok(Value::Int(a ^ b)),
|
||||||
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} right by {r:#}"),
|
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot bitwise xor {l:#} and {r:#}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +441,19 @@ impl BitOr<Value> for Value {
|
||||||
use Value as V;
|
use Value as V;
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(V::Int(a), V::Int(b)) => Ok(Value::Int(a | b)),
|
(V::Int(a), V::Int(b)) => Ok(Value::Int(a | b)),
|
||||||
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot shift {l:#} right by {r:#}"),
|
(l, r) => throw!(*SYM_TYPE_ERROR, "cannot bitwise or {l:#} and {r:#}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Not for Value {
|
||||||
|
type Output = Result<Value>;
|
||||||
|
|
||||||
|
fn not(self) -> Self::Output {
|
||||||
|
use Value as V;
|
||||||
|
match self {
|
||||||
|
V::Int(a) => Ok(Value::Int(!a)),
|
||||||
|
v => throw!(*SYM_TYPE_ERROR, "cannot bitwise not {v:#}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
ops::Not,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
};
|
};
|
||||||
|
@ -84,6 +85,7 @@ pub fn unary_op(o: UnaryOp, a: Value) -> Result<Value> {
|
||||||
match o {
|
match o {
|
||||||
UnaryOp::Neg => -a,
|
UnaryOp::Neg => -a,
|
||||||
UnaryOp::Not => Ok(Value::Bool(!a.truthy())),
|
UnaryOp::Not => Ok(Value::Bool(!a.truthy())),
|
||||||
|
UnaryOp::BitNot => a.not(),
|
||||||
UnaryOp::RangeEndless => a.range_endless(),
|
UnaryOp::RangeEndless => a.range_endless(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +245,7 @@ impl Vm {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_interrupt(&mut self) -> Result<()> {
|
pub fn check_interrupt(&mut self) -> Result<()> {
|
||||||
if self
|
if self
|
||||||
.interrupt
|
.interrupt
|
||||||
.fetch_and(false, std::sync::atomic::Ordering::Relaxed)
|
.fetch_and(false, std::sync::atomic::Ordering::Relaxed)
|
||||||
|
@ -399,7 +401,11 @@ impl Vm {
|
||||||
for _ in 0..n {
|
for _ in 0..n {
|
||||||
let v = self.pop();
|
let v = self.pop();
|
||||||
let k = self.pop();
|
let k = self.pop();
|
||||||
table.insert(k.try_into()?, v);
|
if v == Value::Nil {
|
||||||
|
table.remove(&k.try_into()?);
|
||||||
|
} else {
|
||||||
|
table.insert(k.try_into()?, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.push(table.into());
|
self.push(table.into());
|
||||||
}
|
}
|
||||||
|
@ -415,18 +421,22 @@ impl Vm {
|
||||||
// can't panic: pop_n checked that ext would have len 2*n
|
// can't panic: pop_n checked that ext would have len 2*n
|
||||||
let v = ext.pop().unwrap();
|
let v = ext.pop().unwrap();
|
||||||
let k = ext.pop().unwrap();
|
let k = ext.pop().unwrap();
|
||||||
table_ref.insert(k.try_into()?, v);
|
if v == Value::Nil {
|
||||||
|
table_ref.remove(&k.try_into()?);
|
||||||
|
} else {
|
||||||
|
table_ref.insert(k.try_into()?, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drop(table_ref);
|
drop(table_ref);
|
||||||
self.push(Value::Table(table));
|
self.push(Value::Table(table));
|
||||||
}
|
}
|
||||||
// [ct, idx] -> [ct!idx]
|
// [ct, idx] -> [ct[idx]]
|
||||||
I::Index => {
|
I::Index => {
|
||||||
let idx = self.pop();
|
let idx = self.pop();
|
||||||
let ct = self.pop();
|
let ct = self.pop();
|
||||||
self.push(ct.index(idx)?);
|
self.push(ct.index(idx)?);
|
||||||
}
|
}
|
||||||
// [ct, idx, v] -> [v], ct!idx = v
|
// [ct, idx, v] -> [v], ct[idx] = v
|
||||||
I::StoreIndex => {
|
I::StoreIndex => {
|
||||||
let v = self.pop();
|
let v = self.pop();
|
||||||
let idx = self.pop();
|
let idx = self.pop();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use talc_lang::{compiler::compile, optimize, parser, value::Value, Vm};
|
use talc_lang::{compiler::compile, optimize::optimize, parser, value::Value, vm::Vm};
|
||||||
|
|
||||||
fn assert_eval(src: &str, value: Value) {
|
fn assert_eval(src: &str, value: Value) {
|
||||||
let mut ex = parser::parse(src).expect(&format!("failed to parse expression"));
|
let mut ex = parser::parse(src).expect(&format!("failed to parse expression"));
|
||||||
|
@ -88,7 +88,7 @@ fn closures() {
|
||||||
assert_eval(
|
assert_eval(
|
||||||
"
|
"
|
||||||
var x = 2
|
var x = 2
|
||||||
next = \\-> do x = x * 2 + 1 end
|
next = \\. do x = x * 2 + 1 end
|
||||||
next() + next() + next()
|
next() + next() + next()
|
||||||
",
|
",
|
||||||
Value::Int(5 + 11 + 23),
|
Value::Int(5 + 11 + 23),
|
||||||
|
|
|
@ -7,9 +7,10 @@ edition = "2021"
|
||||||
talc-lang = { path = "../talc-lang" }
|
talc-lang = { path = "../talc-lang" }
|
||||||
talc-macros = { path = "../talc-macros" }
|
talc-macros = { path = "../talc-macros" }
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
regex = "1.11"
|
regex = { version = "1.11", optional = true }
|
||||||
rand = { version = "0.8", optional = true }
|
rand = { version = "0.8", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["random"]
|
default = ["rand", "regex"]
|
||||||
random = ["dep:rand"]
|
rand = ["dep:rand"]
|
||||||
|
regex = ["dep:regex"]
|
||||||
|
|
|
@ -5,7 +5,8 @@ use talc_lang::{
|
||||||
symbol::{symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{function::NativeFunc, Value},
|
value::{function::NativeFunc, Value},
|
||||||
vmcall, Vm,
|
vm::Vm,
|
||||||
|
vmcall,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use talc_lang::{
|
||||||
exception::{throw, Exception, Result},
|
exception::{throw, Exception, Result},
|
||||||
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
value::Value,
|
value::Value,
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use talc_lang::{
|
||||||
symbol::{symbol, Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{symbol, Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{function::NativeFunc, HashValue, NativeValue, Value},
|
value::{function::NativeFunc, HashValue, NativeValue, Value},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use talc_lang::{
|
||||||
symbol::SYM_TYPE_ERROR,
|
symbol::SYM_TYPE_ERROR,
|
||||||
throw,
|
throw,
|
||||||
value::{Complex64, Rational64, Value},
|
value::{Complex64, Rational64, Value},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ use talc_lang::{
|
||||||
lstring::LString,
|
lstring::LString,
|
||||||
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
value::Value,
|
value::Value,
|
||||||
vmcall, Vm,
|
vm::Vm,
|
||||||
|
vmcall,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ use talc_lang::{
|
||||||
symbol::{symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{function::NativeFunc, ops::RatioExt, range::RangeType, HashValue, Value},
|
value::{function::NativeFunc, ops::RatioExt, range::RangeType, HashValue, Value},
|
||||||
vmcall, vmcalliter, Vm,
|
vm::Vm,
|
||||||
|
vmcall, vmcalliter,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use talc_lang::{
|
use talc_lang::{
|
||||||
symbol::{symbol, Symbol},
|
symbol::{symbol, Symbol},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod collection;
|
pub mod collection;
|
||||||
|
@ -12,25 +12,29 @@ pub mod format;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod iter;
|
pub mod iter;
|
||||||
pub mod num;
|
pub mod num;
|
||||||
#[cfg(feature = "random")]
|
|
||||||
pub mod random;
|
|
||||||
pub mod regex;
|
|
||||||
pub mod string;
|
pub mod string;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
|
pub mod random;
|
||||||
|
#[cfg(feature = "regex")]
|
||||||
|
pub mod regex;
|
||||||
|
|
||||||
pub fn load_all(vm: &mut Vm) {
|
pub fn load_all(vm: &mut Vm) {
|
||||||
value::load(vm);
|
|
||||||
exception::load(vm);
|
|
||||||
iter::load(vm);
|
|
||||||
collection::load(vm);
|
collection::load(vm);
|
||||||
num::load(vm);
|
exception::load(vm);
|
||||||
io::load(vm);
|
|
||||||
string::load(vm);
|
|
||||||
format::load(vm);
|
|
||||||
regex::load(vm);
|
|
||||||
file::load(vm);
|
file::load(vm);
|
||||||
#[cfg(feature = "random")]
|
format::load(vm);
|
||||||
|
io::load(vm);
|
||||||
|
iter::load(vm);
|
||||||
|
num::load(vm);
|
||||||
|
string::load(vm);
|
||||||
|
value::load(vm);
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
random::load(vm);
|
random::load(vm);
|
||||||
|
#[cfg(feature = "regex")]
|
||||||
|
regex::load(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
|
|
|
@ -7,7 +7,8 @@ use talc_lang::{
|
||||||
symbol::{Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{ops::RatioExt, Complex64, Value},
|
value::{ops::RatioExt, Complex64, Value},
|
||||||
vmcalliter, Vm,
|
vm::Vm,
|
||||||
|
vmcalliter,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ use talc_lang::{
|
||||||
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{range::RangeType, Value},
|
value::{range::RangeType, Value},
|
||||||
vmcalliter, Vm,
|
vm::Vm,
|
||||||
|
vmcalliter,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use talc_lang::{
|
||||||
symbol::{Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{NativeValue, Value},
|
value::{NativeValue, Value},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use talc_lang::{
|
||||||
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::Value,
|
value::Value,
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use talc_lang::{
|
||||||
symbol::{symbol, Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
symbol::{symbol, Symbol, SYM_TYPE_ERROR, SYM_VALUE_ERROR},
|
||||||
throw,
|
throw,
|
||||||
value::{ops::RatioExt, HashValue, Rational64, Value},
|
value::{ops::RatioExt, HashValue, Rational64, Value},
|
||||||
Vm,
|
vm::Vm,
|
||||||
};
|
};
|
||||||
use talc_macros::native_func;
|
use talc_macros::native_func;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue