mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
added arrow syntax for forcing output types and added the "any" type (which is basically useless and will likely change in the future)
This commit is contained in:
parent
efe8a177dc
commit
db0be51fa4
@ -1,8 +1,23 @@
|
||||
# mers statements overview
|
||||
# Mers statements overview
|
||||
|
||||
This is the documentation for mers statements.
|
||||
In code, statements are represented by `SStatement`, `SStatementEnum`, `RStatement`, and `RStatementEnum`.
|
||||
|
||||
## statement prefixes
|
||||
|
||||
A statement can be prefixed with any number of stars `*`. This is called dereferencing and turns a reference to a value into the value itself. Modifying the value after a dereference leaves the value the reference was pointing to untouched (the data will be cloned to achieve this).
|
||||
|
||||
A statement can also be prefixed with an arrow followed by the type the statement will have: `-> int/float 12`.
|
||||
Although the statement will always return an `int`, mers will assume that it could also return a float.
|
||||
If the statement's output doesn't fit in the forced type (`-> int "text"`), mers will generate an error.
|
||||
In combination with functions, this is similar to rust's syntax:
|
||||
|
||||
fn my_func(a int, b int) -> int {
|
||||
a + b
|
||||
}
|
||||
|
||||
# Different statements
|
||||
|
||||
## Value
|
||||
|
||||
A statement that always returns a certain value: `10`, `"Hello, World"`, ...
|
||||
|
3
examples/force_output_type.mers
Normal file
3
examples/force_output_type.mers
Normal file
@ -0,0 +1,3 @@
|
||||
fn plus(a int, b int) -> int { a + b }
|
||||
|
||||
10.plus(20).debug()
|
13
examples/the_any_type.mers
Normal file
13
examples/the_any_type.mers
Normal file
@ -0,0 +1,13 @@
|
||||
fn debug_any(val any) {
|
||||
val.debug()
|
||||
}
|
||||
|
||||
"something".debug_any()
|
||||
|
||||
fn just_return(val any) {
|
||||
val
|
||||
}.debug()
|
||||
|
||||
v := "text"
|
||||
v.debug()
|
||||
v.just_return().debug()
|
@ -979,7 +979,7 @@ impl BuiltinFunction {
|
||||
run_input_types.push(val.out_single());
|
||||
*var.lock().unwrap() = val;
|
||||
}
|
||||
let out_type = f.out(&run_input_types);
|
||||
let out_type = f.out(&run_input_types, &info);
|
||||
let info = Arc::clone(info);
|
||||
let f = Arc::clone(f);
|
||||
VDataEnum::Thread(
|
||||
|
@ -5,7 +5,15 @@ use crate::parsing::{
|
||||
parse::{self, ParseError, ScriptError},
|
||||
};
|
||||
|
||||
use super::{code_runnable::RScript, val_data::VData};
|
||||
use super::{code_parsed::SStatement, code_runnable::RScript, val_data::VData, val_type::VType};
|
||||
|
||||
// macro format is !(macro_type [...])
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Macro {
|
||||
/// Compiles and executes the provided mers code at compile-time and inserts the value
|
||||
StaticMers(VData),
|
||||
}
|
||||
|
||||
pub fn parse_macro(file: &mut File) -> Result<Macro, MacroError> {
|
||||
file.skip_whitespaces();
|
||||
@ -63,12 +71,6 @@ fn parse_mers_code(file: &mut File) -> Result<RScript, MacroError> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Macro {
|
||||
/// Compiles and executes the provided mers code at compile-time and inserts the value
|
||||
StaticMers(VData),
|
||||
}
|
||||
|
||||
impl Display for Macro {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
@ -83,11 +83,11 @@ impl SBlock {
|
||||
#[derive(Debug)]
|
||||
pub struct SFunction {
|
||||
pub inputs: Vec<(String, VType)>,
|
||||
pub block: SBlock,
|
||||
pub statement: SStatement,
|
||||
}
|
||||
impl SFunction {
|
||||
pub fn new(inputs: Vec<(String, VType)>, block: SBlock) -> Self {
|
||||
Self { inputs, block }
|
||||
pub fn new(inputs: Vec<(String, VType)>, statement: SStatement) -> Self {
|
||||
Self { inputs, statement }
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,8 +268,9 @@ impl FormatGs for SStatement {
|
||||
}
|
||||
// output self
|
||||
if let Some(force_opt) = &self.force_output_type {
|
||||
write!(f, " -> ")?;
|
||||
write!(f, "-> ")?;
|
||||
force_opt.fmtgs(f, info, form, file)?;
|
||||
write!(f, " ")?;
|
||||
}
|
||||
write!(f, "{}", "*".repeat(self.derefs))?;
|
||||
self.statement.fmtgs(f, info, form, file)?;
|
||||
@ -293,14 +294,14 @@ impl FormatGs for SFunction {
|
||||
write!(f, "(")?;
|
||||
for (i, (name, t)) in self.inputs.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, " {name}")?;
|
||||
write!(f, " {name} ")?;
|
||||
} else {
|
||||
write!(f, "{name} ")?;
|
||||
}
|
||||
t.fmtgs(f, info, form, file)?;
|
||||
}
|
||||
write!(f, ") ")?;
|
||||
self.block.fmtgs(f, info, form, file)
|
||||
self.statement.fmtgs(f, info, form, file)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,13 +63,13 @@ pub struct RFunction {
|
||||
pub inputs: Vec<Arc<Mutex<VData>>>,
|
||||
pub input_types: Vec<VType>,
|
||||
pub input_output_map: Vec<(Vec<VSingleType>, VType)>,
|
||||
pub block: RBlock,
|
||||
pub statement: RStatement,
|
||||
}
|
||||
impl RFunction {
|
||||
pub fn run(&self, info: &GSInfo) -> VData {
|
||||
self.block.run(info)
|
||||
self.statement.run(info)
|
||||
}
|
||||
pub fn out(&self, input_types: &Vec<VSingleType>) -> VType {
|
||||
pub fn out(&self, input_types: &Vec<VSingleType>, info: &GlobalScriptInfo) -> VType {
|
||||
self.input_output_map
|
||||
.iter()
|
||||
.find_map(|v| {
|
||||
@ -79,7 +79,7 @@ impl RFunction {
|
||||
None
|
||||
}
|
||||
})
|
||||
.expect("invalid args for function! possible issue with type-checker if this can be reached! feel free to report a bug.")
|
||||
.unwrap_or_else(|| self.statement.out(info))
|
||||
}
|
||||
pub fn out_vt(&self, input_types: &Vec<VType>, info: &GlobalScriptInfo) -> VType {
|
||||
let mut out = VType { types: vec![] };
|
||||
@ -92,10 +92,16 @@ impl RFunction {
|
||||
out = out | otype;
|
||||
}
|
||||
}
|
||||
out
|
||||
if out.types.is_empty() {
|
||||
// this can happen if we used the `any` type in our function signature,
|
||||
// so in that case we just return the most broad type possible.
|
||||
self.statement.out(info)
|
||||
} else {
|
||||
out
|
||||
}
|
||||
}
|
||||
pub fn out_all(&self, info: &GlobalScriptInfo) -> VType {
|
||||
self.block.out(info)
|
||||
self.statement.out(info)
|
||||
}
|
||||
pub fn in_types(&self) -> &Vec<VType> {
|
||||
&self.input_types
|
||||
|
@ -263,12 +263,12 @@ fn get_all_functions(
|
||||
vartype.to()
|
||||
}
|
||||
}
|
||||
// block is parsed multiple times (this is why we get duplicates in stderr):
|
||||
// the statement is parsed multiple times (this is why we get duplicates in stderr):
|
||||
// - n times for the function args to generate the input-output map
|
||||
// - 1 more time here, where the function args aren't single types
|
||||
out.push((
|
||||
inputs.clone(),
|
||||
block(&s.block, ginfo, linfo.clone())?.out(ginfo),
|
||||
statement(&s.statement, ginfo, &mut linfo.clone())?.out(ginfo),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@ -307,7 +307,7 @@ fn function(
|
||||
inputs: input_vars,
|
||||
input_types,
|
||||
input_output_map: all_outs,
|
||||
block: block(&s.block, ginfo, linfo)?,
|
||||
statement: statement(&s.statement, ginfo, &mut linfo.clone())?,
|
||||
})
|
||||
}
|
||||
|
||||
@ -331,7 +331,11 @@ pub fn stypes(t: &mut VType, ginfo: &mut GlobalScriptInfo) -> Result<(), ToRunna
|
||||
}
|
||||
pub fn stype(t: &mut VSingleType, ginfo: &mut GlobalScriptInfo) -> Result<(), ToRunnableError> {
|
||||
match t {
|
||||
VSingleType::Bool | VSingleType::Int | VSingleType::Float | VSingleType::String => (),
|
||||
VSingleType::Any
|
||||
| VSingleType::Bool
|
||||
| VSingleType::Int
|
||||
| VSingleType::Float
|
||||
| VSingleType::String => (),
|
||||
VSingleType::Tuple(v) => {
|
||||
for t in v {
|
||||
stypes(t, ginfo)?;
|
||||
@ -398,7 +402,7 @@ fn statement_adv(
|
||||
// eprintln!(" --> {}", t.0);
|
||||
// }
|
||||
let mut state = match &*s.statement {
|
||||
SStatementEnum::Value(v) => RStatementEnum::Value(v.clone()),
|
||||
SStatementEnum::Value(v) => RStatementEnum::Value(v.clone()).to(),
|
||||
SStatementEnum::Tuple(v) | SStatementEnum::List(v) => {
|
||||
let mut w = Vec::with_capacity(v.len());
|
||||
let mut prev = None;
|
||||
@ -425,6 +429,7 @@ fn statement_adv(
|
||||
} else {
|
||||
RStatementEnum::Tuple(w)
|
||||
}
|
||||
.to()
|
||||
}
|
||||
SStatementEnum::Variable(v, is_ref) => {
|
||||
let existing_var = linfo.vars.get(v);
|
||||
@ -465,6 +470,7 @@ fn statement_adv(
|
||||
} else {
|
||||
return Err(ToRunnableError::UseOfUndefinedVariable(v.clone()));
|
||||
}
|
||||
.to()
|
||||
}
|
||||
SStatementEnum::FunctionCall(v, args) => {
|
||||
let mut rargs = Vec::with_capacity(args.len());
|
||||
@ -553,6 +559,7 @@ fn statement_adv(
|
||||
}
|
||||
}
|
||||
}
|
||||
.to(),
|
||||
SStatementEnum::FunctionDefinition(name, f) => {
|
||||
let f = Arc::new(function(f, ginfo, linfo.clone())?);
|
||||
if let Some(name) = name {
|
||||
@ -564,9 +571,9 @@ fn statement_adv(
|
||||
linfo.fns.insert(name.clone(), vec![f]);
|
||||
}
|
||||
}
|
||||
RStatementEnum::Value(VDataEnum::Function(f).to())
|
||||
RStatementEnum::Value(VDataEnum::Function(f).to()).to()
|
||||
}
|
||||
SStatementEnum::Block(b) => RStatementEnum::Block(block(&b, ginfo, linfo.clone())?),
|
||||
SStatementEnum::Block(b) => RStatementEnum::Block(block(&b, ginfo, linfo.clone())?).to(),
|
||||
SStatementEnum::If(c, t, e) => RStatementEnum::If(
|
||||
{
|
||||
let condition = statement(&c, ginfo, linfo)?;
|
||||
@ -591,8 +598,9 @@ fn statement_adv(
|
||||
Some(v) => Some(statement(&v, ginfo, linfo)?),
|
||||
None => None,
|
||||
},
|
||||
),
|
||||
SStatementEnum::Loop(c) => RStatementEnum::Loop(statement(&c, ginfo, linfo)?),
|
||||
)
|
||||
.to(),
|
||||
SStatementEnum::Loop(c) => RStatementEnum::Loop(statement(&c, ginfo, linfo)?).to(),
|
||||
SStatementEnum::For(v, c, b) => {
|
||||
let mut linfo = linfo.clone();
|
||||
let container = statement(&c, ginfo, &mut linfo)?;
|
||||
@ -603,7 +611,7 @@ fn statement_adv(
|
||||
let assign_to = statement_adv(v, ginfo, &mut linfo, &mut Some((inner, &mut true)))?;
|
||||
let block = statement(&b, ginfo, &mut linfo)?;
|
||||
let o = RStatementEnum::For(assign_to, container, block);
|
||||
o
|
||||
o.to()
|
||||
}
|
||||
|
||||
SStatementEnum::Switch(switch_on, cases, force) => {
|
||||
@ -639,7 +647,7 @@ fn statement_adv(
|
||||
}));
|
||||
}
|
||||
}
|
||||
RStatementEnum::Switch(switch_on, ncases, *force)
|
||||
RStatementEnum::Switch(switch_on, ncases, *force).to()
|
||||
}
|
||||
SStatementEnum::Match(cases) => {
|
||||
let mut ncases: Vec<(RStatement, RStatement, RStatement)> =
|
||||
@ -667,13 +675,13 @@ fn statement_adv(
|
||||
out_type = out_type | VSingleType::Tuple(vec![]).to();
|
||||
}
|
||||
|
||||
RStatementEnum::Match(ncases)
|
||||
RStatementEnum::Match(ncases).to()
|
||||
}
|
||||
|
||||
SStatementEnum::IndexFixed(st, i) => {
|
||||
let st = statement(st, ginfo, linfo)?;
|
||||
if st.out(ginfo).get_always(*i, ginfo).is_some() {
|
||||
RStatementEnum::IndexFixed(st, *i)
|
||||
RStatementEnum::IndexFixed(st, *i).to()
|
||||
} else {
|
||||
return Err(ToRunnableError::NotIndexableFixed(st.out(ginfo), *i));
|
||||
}
|
||||
@ -689,7 +697,8 @@ fn statement_adv(
|
||||
}
|
||||
},
|
||||
statement(s, ginfo, linfo)?,
|
||||
),
|
||||
)
|
||||
.to(),
|
||||
SStatementEnum::TypeDefinition(name, t) => {
|
||||
// insert to name map has to happen before stypes()
|
||||
ginfo
|
||||
@ -698,13 +707,12 @@ fn statement_adv(
|
||||
let mut t = t.to_owned();
|
||||
stypes(&mut t, ginfo)?;
|
||||
ginfo.custom_types.push(t);
|
||||
RStatementEnum::Value(VDataEnum::Tuple(vec![]).to())
|
||||
RStatementEnum::Value(VDataEnum::Tuple(vec![]).to()).to()
|
||||
}
|
||||
SStatementEnum::Macro(m) => match m {
|
||||
Macro::StaticMers(val) => RStatementEnum::Value(val.clone()),
|
||||
Macro::StaticMers(val) => RStatementEnum::Value(val.clone()).to(),
|
||||
},
|
||||
}
|
||||
.to();
|
||||
};
|
||||
state.derefs = s.derefs;
|
||||
// if force_output_type is set, verify that the real output type actually fits in the forced one.
|
||||
if let Some(force_opt) = &s.force_output_type {
|
||||
|
@ -18,6 +18,7 @@ pub struct VType {
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum VSingleType {
|
||||
Any,
|
||||
Bool,
|
||||
Int,
|
||||
Float,
|
||||
@ -37,7 +38,8 @@ impl VSingleType {
|
||||
/// None => Cannot get, Some(t) => getting can return t or nothing
|
||||
pub fn get(&self, i: usize, gsinfo: &GlobalScriptInfo) -> Option<VType> {
|
||||
match self {
|
||||
Self::Bool
|
||||
Self::Any
|
||||
| Self::Bool
|
||||
| Self::Int
|
||||
| Self::Float
|
||||
| Self::Function(..)
|
||||
@ -56,7 +58,8 @@ impl VSingleType {
|
||||
}
|
||||
pub fn get_ref(&self, i: usize, gsinfo: &GlobalScriptInfo) -> Option<VType> {
|
||||
match self {
|
||||
Self::Bool
|
||||
Self::Any
|
||||
| Self::Bool
|
||||
| Self::Int
|
||||
| Self::Float
|
||||
| Self::Function(..)
|
||||
@ -76,7 +79,8 @@ impl VSingleType {
|
||||
/// None => might not always return t, Some(t) => can only return t
|
||||
pub fn get_always(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
match self {
|
||||
Self::Bool
|
||||
Self::Any
|
||||
| Self::Bool
|
||||
| Self::Int
|
||||
| Self::Float
|
||||
| Self::String
|
||||
@ -95,7 +99,8 @@ impl VSingleType {
|
||||
}
|
||||
pub fn get_always_ref(&self, i: usize, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
match self {
|
||||
Self::Bool
|
||||
Self::Any
|
||||
| Self::Bool
|
||||
| Self::Int
|
||||
| Self::Float
|
||||
| Self::String
|
||||
@ -179,7 +184,12 @@ impl VType {
|
||||
impl VSingleType {
|
||||
pub fn get_any(&self, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
match self {
|
||||
Self::Bool | Self::Int | Self::Float | Self::Function(..) | Self::Thread(..) => None,
|
||||
Self::Any
|
||||
| Self::Bool
|
||||
| Self::Int
|
||||
| Self::Float
|
||||
| Self::Function(..)
|
||||
| Self::Thread(..) => None,
|
||||
Self::String => Some(VSingleType::String.into()),
|
||||
Self::Tuple(t) => Some(t.iter().fold(VType { types: vec![] }, |a, b| a | b)),
|
||||
Self::List(t) => Some(t.clone()),
|
||||
@ -192,7 +202,12 @@ impl VSingleType {
|
||||
}
|
||||
pub fn get_any_ref(&self, info: &GlobalScriptInfo) -> Option<VType> {
|
||||
match self {
|
||||
Self::Bool | Self::Int | Self::Float | Self::Function(..) | Self::Thread(..) => None,
|
||||
Self::Any
|
||||
| Self::Bool
|
||||
| Self::Int
|
||||
| Self::Float
|
||||
| Self::Function(..)
|
||||
| Self::Thread(..) => None,
|
||||
Self::String => Some(VSingleType::String.into()),
|
||||
Self::Tuple(t) => Some(
|
||||
t.iter()
|
||||
@ -378,7 +393,7 @@ impl VSingleType {
|
||||
/// converts all Self::EnumVariantS to Self::EnumVariant
|
||||
pub fn enum_variants(&mut self, enum_variants: &mut HashMap<String, usize>) {
|
||||
match self {
|
||||
Self::Bool | Self::Int | Self::Float | Self::String => (),
|
||||
Self::Any | Self::Bool | Self::Int | Self::Float | Self::String => (),
|
||||
Self::Tuple(v) => {
|
||||
for t in v {
|
||||
t.enum_variants(enum_variants);
|
||||
@ -412,6 +427,8 @@ impl VSingleType {
|
||||
}
|
||||
pub fn fits_in(&self, rhs: &Self, info: &GlobalScriptInfo) -> bool {
|
||||
let o = match (self, rhs) {
|
||||
(_, Self::Any) => true,
|
||||
(Self::Any, _) => false,
|
||||
(Self::Reference(r), Self::Reference(b)) => r.fits_in(b, info),
|
||||
(Self::Reference(_), _) | (_, Self::Reference(_)) => false,
|
||||
(Self::EnumVariant(v1, t1), Self::EnumVariant(v2, t2)) => {
|
||||
@ -526,6 +543,7 @@ impl FormatGs for VSingleType {
|
||||
file: Option<&crate::parsing::file::File>,
|
||||
) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Any => write!(f, "any"),
|
||||
Self::Bool => write!(f, "bool"),
|
||||
Self::Int => write!(f, "int"),
|
||||
Self::Float => write!(f, "float"),
|
||||
@ -649,7 +667,7 @@ impl FormatGs for VType {
|
||||
}
|
||||
t.fmtgs(f, info, form, file)?;
|
||||
}
|
||||
Ok(())
|
||||
write!(f, ",")
|
||||
}
|
||||
}
|
||||
impl Display for VType {
|
||||
|
@ -390,6 +390,7 @@ impl ByteData for VType {
|
||||
impl ByteDataA for VSingleType {
|
||||
fn as_byte_data(&self, vec: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Any => vec.push(b'a'),
|
||||
Self::Bool => vec.push(b'b'),
|
||||
Self::Int => vec.push(b'i'),
|
||||
Self::Float => vec.push(b'f'),
|
||||
@ -438,6 +439,7 @@ impl ByteData for VSingleType {
|
||||
let mut switch_byte = [0u8];
|
||||
data.read_exact(&mut switch_byte)?;
|
||||
Ok(match switch_byte[0] {
|
||||
b'a' => Self::Any,
|
||||
b'b' => Self::Bool,
|
||||
b'i' => Self::Int,
|
||||
b'f' => Self::Float,
|
||||
|
@ -192,7 +192,7 @@ pub fn parse_step_interpret(
|
||||
"args".to_string(),
|
||||
VSingleType::List(VSingleType::String.into()).to(),
|
||||
)],
|
||||
parse_block_advanced(file, Some(false), true, true, false)?,
|
||||
SStatementEnum::Block(parse_block_advanced(file, Some(false), false, true, false)?).to(),
|
||||
);
|
||||
if ginfo.log.after_parse.log() {
|
||||
ginfo.log.log(LogMsg::AfterParse(
|
||||
@ -543,6 +543,18 @@ pub mod implementation {
|
||||
) -> Result<SStatement, ParseError> {
|
||||
file.skip_whitespaces();
|
||||
let err_start_of_statement = *file.get_pos();
|
||||
// force output type
|
||||
let force_opt = if file[file.get_pos().current_char_index..].starts_with("->") {
|
||||
file.next();
|
||||
file.next();
|
||||
file.skip_whitespaces();
|
||||
let o = parse_type(file)?;
|
||||
file.skip_whitespaces();
|
||||
Some(o)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
// derefs
|
||||
let mut derefs = 0;
|
||||
loop {
|
||||
if let Some('*') = file.peek() {
|
||||
@ -836,6 +848,7 @@ pub mod implementation {
|
||||
}
|
||||
};
|
||||
out.derefs = derefs;
|
||||
out.force_output_type = force_opt;
|
||||
let err_end_of_original_statement = *file.get_pos();
|
||||
// special characters that can follow a statement (loop because these can be chained)
|
||||
loop {
|
||||
@ -1070,6 +1083,7 @@ pub mod implementation {
|
||||
} else {
|
||||
loop {
|
||||
let mut arg_name = String::new();
|
||||
file.skip_whitespaces();
|
||||
loop {
|
||||
let err_fn_arg_name_start = *file.get_pos();
|
||||
match file.next() {
|
||||
@ -1100,7 +1114,7 @@ pub mod implementation {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(SFunction::new(args, parse_block(file)?))
|
||||
Ok(SFunction::new(args, parse_statement(file)?))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_type(file: &mut File) -> Result<VType, ParseError> {
|
||||
@ -1122,7 +1136,6 @@ pub mod implementation {
|
||||
closed_fn_args = true;
|
||||
break;
|
||||
}
|
||||
file.skip_whitespaces();
|
||||
match file.peek() {
|
||||
Some('/') => {
|
||||
file.next();
|
||||
@ -1132,8 +1145,15 @@ pub mod implementation {
|
||||
file.next();
|
||||
break;
|
||||
}
|
||||
Some(_) => break,
|
||||
|
||||
Some(ch) if ch.is_whitespace() => break,
|
||||
Some(ch) if ch == ',' => {
|
||||
file.next();
|
||||
break;
|
||||
}
|
||||
Some(ch) => {
|
||||
eprintln!("[warn] stopped parsing type at character {ch} (unexpected character, moving on...)");
|
||||
break;
|
||||
}
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
@ -1201,8 +1221,7 @@ pub mod implementation {
|
||||
let mut name = ch.to_string();
|
||||
loop {
|
||||
match file.peek() {
|
||||
Some(']') => break,
|
||||
Some('/') => break,
|
||||
Some(']' | '/' | ',') => break,
|
||||
Some(')') if in_fn_args => {
|
||||
file.next();
|
||||
closed_bracket_in_fn_args = true;
|
||||
@ -1315,6 +1334,7 @@ pub mod implementation {
|
||||
}
|
||||
}
|
||||
match name.trim().to_lowercase().as_str() {
|
||||
"any" => VSingleType::Any,
|
||||
"bool" => VSingleType::Bool,
|
||||
"int" => VSingleType::Int,
|
||||
"float" => VSingleType::Float,
|
||||
|
Loading…
Reference in New Issue
Block a user