Begin standard library
This commit is contained in:
parent
cb56fd05cd
commit
9bb4e1b944
@ -20,8 +20,6 @@ impl MapIndex {
|
|||||||
|
|
||||||
impl AbstractNode for MapIndex {
|
impl AbstractNode for MapIndex {
|
||||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
let left_type = self.left.node.expected_type(context)?;
|
|
||||||
|
|
||||||
if let (
|
if let (
|
||||||
Expression::Identifier(collection_identifier),
|
Expression::Identifier(collection_identifier),
|
||||||
Expression::Identifier(index_identifier),
|
Expression::Identifier(index_identifier),
|
||||||
@ -72,7 +70,7 @@ impl AbstractNode for MapIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Err(ValidationError::CannotIndexWith {
|
Err(ValidationError::CannotIndexWith {
|
||||||
collection_type: left_type,
|
collection_type: self.left.node.expected_type(context)?,
|
||||||
collection_position: self.left.position,
|
collection_position: self.left.position,
|
||||||
index_type: self.right.node.expected_type(context)?,
|
index_type: self.right.node.expected_type(context)?,
|
||||||
index_position: self.right.position,
|
index_position: self.right.position,
|
||||||
|
@ -84,7 +84,6 @@ impl AbstractTree {
|
|||||||
(_, _) => Ordering::Equal,
|
(_, _) => Ordering::Equal,
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("{:?}", statements);
|
|
||||||
AbstractTree(statements)
|
AbstractTree(statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
123
dust-lang/src/built_in_functions.rs
Normal file
123
dust-lang/src/built_in_functions.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
use core::fmt;
|
||||||
|
use std::{
|
||||||
|
fmt::{Display, Formatter},
|
||||||
|
io::stdin,
|
||||||
|
thread,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
abstract_tree::{Action, Type},
|
||||||
|
context::Context,
|
||||||
|
error::{RuntimeError, ValidationError},
|
||||||
|
value::ValueInner,
|
||||||
|
Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const BUILT_IN_FUNCTIONS: [BuiltInFunction; 5] = [
|
||||||
|
BuiltInFunction::IntParse,
|
||||||
|
BuiltInFunction::IntRandomRange,
|
||||||
|
BuiltInFunction::ReadLine,
|
||||||
|
BuiltInFunction::WriteLine,
|
||||||
|
BuiltInFunction::Sleep,
|
||||||
|
];
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
pub enum BuiltInFunction {
|
||||||
|
IntParse,
|
||||||
|
IntRandomRange,
|
||||||
|
ReadLine,
|
||||||
|
WriteLine,
|
||||||
|
Sleep,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuiltInFunction {
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
BuiltInFunction::IntParse => "parse",
|
||||||
|
BuiltInFunction::IntRandomRange => "random_range",
|
||||||
|
BuiltInFunction::ReadLine => "read_line",
|
||||||
|
BuiltInFunction::WriteLine => "write_line",
|
||||||
|
BuiltInFunction::Sleep => "sleep",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_value(self) -> Value {
|
||||||
|
Value::built_in_function(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(&self, arguments: Vec<Value>, context: &Context) -> Result<Action, RuntimeError> {
|
||||||
|
match self {
|
||||||
|
BuiltInFunction::IntParse => {
|
||||||
|
let string = arguments.get(0).unwrap();
|
||||||
|
|
||||||
|
if let ValueInner::String(_string) = string.inner().as_ref() {
|
||||||
|
// let integer = string.parse();
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
|
||||||
|
// Ok(Action::Return(Value::integer(integer)))
|
||||||
|
} else {
|
||||||
|
let mut actual = Vec::with_capacity(arguments.len());
|
||||||
|
|
||||||
|
for value in arguments {
|
||||||
|
let r#type = value.r#type(context)?;
|
||||||
|
|
||||||
|
actual.push(r#type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(RuntimeError::ValidationFailure(
|
||||||
|
ValidationError::WrongArguments {
|
||||||
|
expected: vec![Type::String],
|
||||||
|
actual,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuiltInFunction::IntRandomRange => {
|
||||||
|
let range = arguments.get(0).unwrap();
|
||||||
|
|
||||||
|
if let ValueInner::Range(range) = range.inner().as_ref() {
|
||||||
|
let random = thread_rng().gen_range(range.clone());
|
||||||
|
|
||||||
|
Ok(Action::Return(Value::integer(random)))
|
||||||
|
} else {
|
||||||
|
panic!("Built-in function cannot have a non-function type.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuiltInFunction::ReadLine => {
|
||||||
|
let mut input = String::new();
|
||||||
|
|
||||||
|
stdin().read_line(&mut input)?;
|
||||||
|
|
||||||
|
Ok(Action::Return(Value::string(input)))
|
||||||
|
}
|
||||||
|
BuiltInFunction::WriteLine => {
|
||||||
|
println!("{}", arguments[0]);
|
||||||
|
|
||||||
|
Ok(Action::None)
|
||||||
|
}
|
||||||
|
BuiltInFunction::Sleep => {
|
||||||
|
if let ValueInner::Integer(milliseconds) = arguments[0].inner().as_ref() {
|
||||||
|
thread::sleep(Duration::from_millis(*milliseconds as u64));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Action::None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for BuiltInFunction {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
BuiltInFunction::IntParse => write!(f, "(input : int) : str {{ *MAGIC* }}"),
|
||||||
|
BuiltInFunction::IntRandomRange => write!(f, "(input: range) : int {{ *MAGIC* }}"),
|
||||||
|
BuiltInFunction::ReadLine => write!(f, "() : str {{ *MAGIC* }}"),
|
||||||
|
BuiltInFunction::WriteLine => write!(f, "(to_output : any) : none {{ *MAGIC* }}"),
|
||||||
|
BuiltInFunction::Sleep => write!(f, "(milliseconds : int) : none {{ *MAGIC* }}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,6 @@ use std::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
abstract_tree::{Identifier, Type},
|
abstract_tree::{Identifier, Type},
|
||||||
error::{RwLockPoisonError, ValidationError},
|
error::{RwLockPoisonError, ValidationError},
|
||||||
value::{BUILT_IN_FUNCTIONS, BUILT_IN_MODULES},
|
|
||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,18 +59,6 @@ impl Context {
|
|||||||
if self.inner.read()?.contains_key(identifier) {
|
if self.inner.read()?.contains_key(identifier) {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
for module in BUILT_IN_MODULES {
|
|
||||||
if identifier.as_str() == module.name() {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for function in BUILT_IN_FUNCTIONS {
|
|
||||||
if identifier.as_str() == function.name() {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,40 +70,16 @@ impl Context {
|
|||||||
ValueData::Value(value) => value.r#type(self)?,
|
ValueData::Value(value) => value.r#type(self)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(Some(r#type.clone()));
|
Ok(Some(r#type.clone()))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
for module in BUILT_IN_MODULES {
|
|
||||||
if identifier.as_str() == module.name() {
|
|
||||||
return Ok(Some(module.r#type()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for function in BUILT_IN_MODULES {
|
|
||||||
if identifier.as_str() == function.name() {
|
|
||||||
return Ok(Some(function.r#type()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> {
|
pub fn get_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> {
|
||||||
if let Some(ValueData::Value(value)) = self.inner.read()?.get(identifier) {
|
if let Some(ValueData::Value(value)) = self.inner.read()?.get(identifier) {
|
||||||
Ok(Some(value.clone()))
|
Ok(Some(value.clone()))
|
||||||
} else {
|
} else {
|
||||||
for module in BUILT_IN_MODULES {
|
|
||||||
if identifier.as_str() == module.name() {
|
|
||||||
return Ok(Some(module.value()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for function in BUILT_IN_MODULES {
|
|
||||||
if identifier.as_str() == function.name() {
|
|
||||||
return Ok(Some(function.value()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
pub mod abstract_tree;
|
pub mod abstract_tree;
|
||||||
|
pub mod built_in_functions;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
|
use abstract_tree::Identifier;
|
||||||
|
use built_in_functions::BUILT_IN_FUNCTIONS;
|
||||||
use context::Context;
|
use context::Context;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use lexer::lex;
|
use lexer::lex;
|
||||||
@ -13,8 +16,16 @@ pub use value::Value;
|
|||||||
|
|
||||||
pub fn interpret(source: &str) -> Result<Option<Value>, Vec<Error>> {
|
pub fn interpret(source: &str) -> Result<Option<Value>, Vec<Error>> {
|
||||||
let context = Context::new();
|
let context = Context::new();
|
||||||
|
|
||||||
|
for function in BUILT_IN_FUNCTIONS {
|
||||||
|
context
|
||||||
|
.set_value(Identifier::new(function.name()), function.as_value())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let mut interpreter = Interpreter::new(context);
|
let mut interpreter = Interpreter::new(context);
|
||||||
|
|
||||||
|
interpreter.run(include_str!("../../std/io.ds"))?;
|
||||||
interpreter.run(source)
|
interpreter.run(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,14 +2,10 @@ use std::{
|
|||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
io::stdin,
|
|
||||||
ops::Range,
|
ops::Range,
|
||||||
sync::{Arc, OnceLock},
|
sync::Arc,
|
||||||
thread,
|
|
||||||
time::Duration,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use rand::{thread_rng, Rng};
|
|
||||||
use stanza::{
|
use stanza::{
|
||||||
renderer::{console::Console, Renderer},
|
renderer::{console::Console, Renderer},
|
||||||
style::{HAlign, MinWidth, Styles},
|
style::{HAlign, MinWidth, Styles},
|
||||||
@ -18,6 +14,7 @@ use stanza::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
abstract_tree::{AbstractNode, Action, Block, Identifier, Type, WithPosition},
|
abstract_tree::{AbstractNode, Action, Block, Identifier, Type, WithPosition},
|
||||||
|
built_in_functions::BuiltInFunction,
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
};
|
};
|
||||||
@ -225,7 +222,9 @@ impl ValueInner {
|
|||||||
.collect(),
|
.collect(),
|
||||||
return_type: Box::new(parsed_function.return_type.node.clone()),
|
return_type: Box::new(parsed_function.return_type.node.clone()),
|
||||||
},
|
},
|
||||||
Function::BuiltIn(built_in_function) => built_in_function.r#type(),
|
Function::BuiltIn(built_in_function) => {
|
||||||
|
(*built_in_function).as_value().r#type(context)?
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ValueInner::Structure { name, .. } => {
|
ValueInner::Structure { name, .. } => {
|
||||||
if let Some(r#type) = context.get_type(name)? {
|
if let Some(r#type) = context.get_type(name)? {
|
||||||
@ -331,226 +330,3 @@ pub struct ParsedFunction {
|
|||||||
return_type: WithPosition<Type>,
|
return_type: WithPosition<Type>,
|
||||||
body: WithPosition<Block>,
|
body: WithPosition<Block>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT_PARSE: OnceLock<Value> = OnceLock::new();
|
|
||||||
static INT_RANDOM_RANGE: OnceLock<Value> = OnceLock::new();
|
|
||||||
static READ_LINE: OnceLock<Value> = OnceLock::new();
|
|
||||||
static WRITE_LINE: OnceLock<Value> = OnceLock::new();
|
|
||||||
static SLEEP: OnceLock<Value> = OnceLock::new();
|
|
||||||
|
|
||||||
pub const BUILT_IN_FUNCTIONS: [BuiltInFunction; 5] = [
|
|
||||||
BuiltInFunction::IntParse,
|
|
||||||
BuiltInFunction::IntRandomRange,
|
|
||||||
BuiltInFunction::ReadLine,
|
|
||||||
BuiltInFunction::WriteLine,
|
|
||||||
BuiltInFunction::Sleep,
|
|
||||||
];
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
|
||||||
pub enum BuiltInFunction {
|
|
||||||
IntParse,
|
|
||||||
IntRandomRange,
|
|
||||||
ReadLine,
|
|
||||||
WriteLine,
|
|
||||||
Sleep,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BuiltInFunction {
|
|
||||||
pub fn name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
BuiltInFunction::IntParse => "parse",
|
|
||||||
BuiltInFunction::IntRandomRange => "random_range",
|
|
||||||
BuiltInFunction::ReadLine => "read_line",
|
|
||||||
BuiltInFunction::WriteLine => "write_line",
|
|
||||||
BuiltInFunction::Sleep => "sleep",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn value(&self) -> Value {
|
|
||||||
match self {
|
|
||||||
BuiltInFunction::IntParse => {
|
|
||||||
INT_PARSE.get_or_init(|| Value::built_in_function(BuiltInFunction::IntParse))
|
|
||||||
}
|
|
||||||
BuiltInFunction::IntRandomRange => INT_RANDOM_RANGE
|
|
||||||
.get_or_init(|| Value::built_in_function(BuiltInFunction::IntRandomRange)),
|
|
||||||
BuiltInFunction::ReadLine => {
|
|
||||||
READ_LINE.get_or_init(|| Value::built_in_function(BuiltInFunction::ReadLine))
|
|
||||||
}
|
|
||||||
BuiltInFunction::WriteLine => {
|
|
||||||
WRITE_LINE.get_or_init(|| Value::built_in_function(BuiltInFunction::WriteLine))
|
|
||||||
}
|
|
||||||
BuiltInFunction::Sleep => {
|
|
||||||
SLEEP.get_or_init(|| Value::built_in_function(BuiltInFunction::Sleep))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn r#type(&self) -> Type {
|
|
||||||
match self {
|
|
||||||
BuiltInFunction::IntParse => Type::Function {
|
|
||||||
parameter_types: vec![Type::String],
|
|
||||||
return_type: Box::new(Type::Integer),
|
|
||||||
},
|
|
||||||
BuiltInFunction::IntRandomRange => Type::Function {
|
|
||||||
parameter_types: vec![Type::Range],
|
|
||||||
return_type: Box::new(Type::Integer),
|
|
||||||
},
|
|
||||||
BuiltInFunction::ReadLine => Type::Function {
|
|
||||||
parameter_types: Vec::with_capacity(0),
|
|
||||||
return_type: Box::new(Type::String),
|
|
||||||
},
|
|
||||||
BuiltInFunction::WriteLine => Type::Function {
|
|
||||||
parameter_types: vec![Type::Any],
|
|
||||||
return_type: Box::new(Type::None),
|
|
||||||
},
|
|
||||||
BuiltInFunction::Sleep => Type::Function {
|
|
||||||
parameter_types: vec![Type::Integer],
|
|
||||||
return_type: Box::new(Type::None),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn call(&self, arguments: Vec<Value>, context: &Context) -> Result<Action, RuntimeError> {
|
|
||||||
match self {
|
|
||||||
BuiltInFunction::IntParse => {
|
|
||||||
let string = arguments.get(0).unwrap();
|
|
||||||
|
|
||||||
if let ValueInner::String(_string) = string.inner().as_ref() {
|
|
||||||
// let integer = string.parse();
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
|
|
||||||
// Ok(Action::Return(Value::integer(integer)))
|
|
||||||
} else {
|
|
||||||
let mut actual = Vec::with_capacity(arguments.len());
|
|
||||||
|
|
||||||
for value in arguments {
|
|
||||||
let r#type = value.r#type(context)?;
|
|
||||||
|
|
||||||
actual.push(r#type);
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(RuntimeError::ValidationFailure(
|
|
||||||
ValidationError::WrongArguments {
|
|
||||||
expected: vec![Type::String],
|
|
||||||
actual,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BuiltInFunction::IntRandomRange => {
|
|
||||||
let range = arguments.get(0).unwrap();
|
|
||||||
|
|
||||||
if let ValueInner::Range(range) = range.inner().as_ref() {
|
|
||||||
let random = thread_rng().gen_range(range.clone());
|
|
||||||
|
|
||||||
Ok(Action::Return(Value::integer(random)))
|
|
||||||
} else {
|
|
||||||
panic!("Built-in function cannot have a non-function type.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BuiltInFunction::ReadLine => {
|
|
||||||
let mut input = String::new();
|
|
||||||
|
|
||||||
stdin().read_line(&mut input)?;
|
|
||||||
|
|
||||||
Ok(Action::Return(Value::string(input)))
|
|
||||||
}
|
|
||||||
BuiltInFunction::WriteLine => {
|
|
||||||
println!("{}", arguments[0]);
|
|
||||||
|
|
||||||
Ok(Action::None)
|
|
||||||
}
|
|
||||||
BuiltInFunction::Sleep => {
|
|
||||||
if let ValueInner::Integer(milliseconds) = arguments[0].inner().as_ref() {
|
|
||||||
thread::sleep(Duration::from_millis(*milliseconds as u64));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Action::None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for BuiltInFunction {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
BuiltInFunction::IntParse => write!(f, "(input : int) : str {{ *MAGIC* }}"),
|
|
||||||
BuiltInFunction::IntRandomRange => write!(f, "(input: range) : int {{ *MAGIC* }}"),
|
|
||||||
BuiltInFunction::ReadLine => write!(f, "() : str {{ *MAGIC* }}"),
|
|
||||||
BuiltInFunction::WriteLine => write!(f, "(to_output : any) : none {{ *MAGIC* }}"),
|
|
||||||
BuiltInFunction::Sleep => write!(f, "(milliseconds : int) : none {{ *MAGIC* }}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INT: OnceLock<Value> = OnceLock::new();
|
|
||||||
static IO: OnceLock<Value> = OnceLock::new();
|
|
||||||
static THREAD: OnceLock<Value> = OnceLock::new();
|
|
||||||
|
|
||||||
pub const BUILT_IN_MODULES: [BuiltInModule; 3] =
|
|
||||||
[BuiltInModule::Int, BuiltInModule::Io, BuiltInModule::Thread];
|
|
||||||
|
|
||||||
pub enum BuiltInModule {
|
|
||||||
Int,
|
|
||||||
Io,
|
|
||||||
Thread,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BuiltInModule {
|
|
||||||
pub fn name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
BuiltInModule::Int => "int",
|
|
||||||
BuiltInModule::Io => "io",
|
|
||||||
BuiltInModule::Thread => "thread",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn value(self) -> Value {
|
|
||||||
match self {
|
|
||||||
BuiltInModule::Int => {
|
|
||||||
let mut properties = BTreeMap::new();
|
|
||||||
|
|
||||||
properties.insert(
|
|
||||||
Identifier::new("parse"),
|
|
||||||
Value::built_in_function(BuiltInFunction::IntParse),
|
|
||||||
);
|
|
||||||
properties.insert(
|
|
||||||
Identifier::new("random_range"),
|
|
||||||
Value::built_in_function(BuiltInFunction::IntRandomRange),
|
|
||||||
);
|
|
||||||
|
|
||||||
INT.get_or_init(|| Value::map(properties)).clone()
|
|
||||||
}
|
|
||||||
BuiltInModule::Io => {
|
|
||||||
let mut properties = BTreeMap::new();
|
|
||||||
|
|
||||||
properties.insert(
|
|
||||||
Identifier::new("read_line"),
|
|
||||||
Value::built_in_function(BuiltInFunction::ReadLine),
|
|
||||||
);
|
|
||||||
properties.insert(
|
|
||||||
Identifier::new("write_line"),
|
|
||||||
Value::built_in_function(BuiltInFunction::WriteLine),
|
|
||||||
);
|
|
||||||
|
|
||||||
IO.get_or_init(|| Value::map(properties)).clone()
|
|
||||||
}
|
|
||||||
BuiltInModule::Thread => {
|
|
||||||
let mut properties = BTreeMap::new();
|
|
||||||
|
|
||||||
properties.insert(
|
|
||||||
Identifier::new("sleep"),
|
|
||||||
Value::built_in_function(BuiltInFunction::Sleep),
|
|
||||||
);
|
|
||||||
|
|
||||||
THREAD.get_or_init(|| Value::map(properties)).clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn r#type(self) -> Type {
|
|
||||||
Type::Map
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -10,7 +10,7 @@ use std::{
|
|||||||
io::{stderr, Write},
|
io::{stderr, Write},
|
||||||
};
|
};
|
||||||
|
|
||||||
use dust_lang::{context::Context, Interpreter};
|
use dust_lang::{context::Context, interpret};
|
||||||
|
|
||||||
/// Command-line arguments to be parsed.
|
/// Command-line arguments to be parsed.
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@ -46,9 +46,7 @@ fn main() {
|
|||||||
return run_shell(context);
|
return run_shell(context);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut interpreter = Interpreter::new(context);
|
let eval_result = interpret(&source);
|
||||||
|
|
||||||
let eval_result = interpreter.run(&source);
|
|
||||||
|
|
||||||
match eval_result {
|
match eval_result {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user