mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
added := for initialization/declaration
This commit is contained in:
parent
8e16140b0f
commit
b4b33b1c82
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@ type elem [int []/elem]
|
|||||||
fn print_linked_list(start elem) {
|
fn print_linked_list(start elem) {
|
||||||
loop {
|
loop {
|
||||||
println(start.0.to_string())
|
println(start.0.to_string())
|
||||||
elem = start.1
|
elem := start.1
|
||||||
switch! elem {
|
switch! elem {
|
||||||
[] {
|
[] {
|
||||||
println("[END]")
|
println("[END]")
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
list = [1 2 3 4 5 6 7 8 9 ...]
|
list := [1 2 3 4 5 6 7 8 9 ...]
|
||||||
|
|
||||||
// calling get on an &list will get a reference
|
// calling get on an &list will get a reference
|
||||||
&list.get(2).assume1() = 24
|
&list.get(2).assume1() = 24
|
||||||
// calling get on a list will get a value
|
// calling get on a list will get a value
|
||||||
should_not_be_changeable = list.get(3).assume1()
|
should_not_be_changeable := list.get(3).assume1()
|
||||||
&should_not_be_changeable = 24
|
&should_not_be_changeable = 24
|
||||||
|
|
||||||
if list.get(2) != [24] println("[!!] list.get(2) != 24 (was {0})".format(list.get(2).to_string()))
|
if list.get(2) != [24] println("[!!] list.get(2) != 24 (was {0})".format(list.get(2).to_string()))
|
||||||
|
@ -4,7 +4,7 @@ fn map_string_to_int(list [string ...] func fn((string int))) {
|
|||||||
// this function will be called by the for loop
|
// this function will be called by the for loop
|
||||||
// whenever it wants to retrieve the next item in the collection.
|
// whenever it wants to retrieve the next item in the collection.
|
||||||
// get the element
|
// get the element
|
||||||
elem = &list.remove(0)
|
elem := &list.remove(0)
|
||||||
switch! elem {
|
switch! elem {
|
||||||
// if the element was present, run the map function to convert it from a string to an int and return the result
|
// if the element was present, run the map function to convert it from a string to an int and return the result
|
||||||
[string] {
|
[string] {
|
||||||
@ -24,8 +24,8 @@ for v ["1" "2" "5" "-10" ...].map_string_to_int((s string) s.parse_int().assume1
|
|||||||
// returns an iterator to iteratively compute square numbers
|
// returns an iterator to iteratively compute square numbers
|
||||||
// using the fact that (n+1)^2 = n^2 + 2n + 1
|
// using the fact that (n+1)^2 = n^2 + 2n + 1
|
||||||
fn square_numbers() {
|
fn square_numbers() {
|
||||||
i = 0
|
i := 0
|
||||||
val = 0
|
val := 0
|
||||||
() {
|
() {
|
||||||
&val = val + { 2 * i } + 1
|
&val = val + { 2 * i } + 1
|
||||||
&i = i + 1
|
&i = i + 1
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
val = "some string"
|
val := "some string"
|
||||||
val = !(mers {
|
val := !(mers {
|
||||||
println("macro is running now!")
|
println("macro is running now!")
|
||||||
"macro returned value"
|
"macro returned value"
|
||||||
})
|
})
|
||||||
println(val)
|
println(val)
|
||||||
val = !(mers "my_macro.mers")
|
val := !(mers "my_macro.mers")
|
||||||
println(val)
|
println(val)
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
// NOTE: Might change, but this is the current state of things
|
// NOTE: Might change, but this is the current state of things
|
||||||
x = 10
|
x := 10
|
||||||
t = thread(() {
|
t := thread(() {
|
||||||
sleep(0.25)
|
sleep(0.25)
|
||||||
println(x.to_string())
|
println(x.to_string())
|
||||||
})
|
})
|
||||||
// if this was x = 20 instead, the thread would still be using the old x = 10 value.
|
&x = 20 // -> 20 20 because it modifies the original variable x
|
||||||
&x = 20
|
// x := 20 // -> 10 20 because it shadows the original variable x
|
||||||
t.await()
|
t.await()
|
||||||
|
println(x.to_string())
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
// this is true by default so the example doesn't finish too quickly or too slowly depending on your hardware.
|
// this is true by default so the example doesn't finish too quickly or too slowly depending on your hardware.
|
||||||
// you can set it to false and tweak the max value for a more authentic cpu-heavy workload.
|
// you can set it to false and tweak the max value for a more authentic cpu-heavy workload.
|
||||||
fake_delay = true
|
fake_delay := true
|
||||||
|
|
||||||
// this will be shared between the two threads to report the progress in percent (0-100%).
|
// this will be shared between the two threads to report the progress in percent (0-100%).
|
||||||
progress = 0
|
progress := 0
|
||||||
|
|
||||||
// an anonymous function that sums all numbers from 0 to max.
|
// an anonymous function that sums all numbers from 0 to max.
|
||||||
// it captures the progress variable and uses it to report its status to the main thread, which will periodically print the current progress.
|
// it captures the progress variable and uses it to report its status to the main thread, which will periodically print the current progress.
|
||||||
// once done, it returns a string with the sum of all numbers.
|
// once done, it returns a string with the sum of all numbers.
|
||||||
calculator = (max int) {
|
calculator := (max int) {
|
||||||
sum = 0
|
sum := 0
|
||||||
for i max {
|
for i max {
|
||||||
i = i + 1
|
i := i + 1
|
||||||
// println("i: {0} s: {1}".format(i.to_string() sum.to_string()))
|
// println("i: {0} s: {1}".format(i.to_string() sum.to_string()))
|
||||||
&sum = sum + i
|
&sum = sum + i
|
||||||
if fake_delay sleep(1)
|
if fake_delay sleep(1)
|
||||||
@ -21,7 +21,7 @@ calculator = (max int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start the thread. if fake_delay is true, calculate 1+2+3+4+5+6+7+8+9+10. if fake_delay is false, count up to some ridiculously large number.
|
// start the thread. if fake_delay is true, calculate 1+2+3+4+5+6+7+8+9+10. if fake_delay is false, count up to some ridiculously large number.
|
||||||
slow_calculation_thread = calculator.thread(if fake_delay 10 else 20000000)
|
slow_calculation_thread := calculator.thread(if fake_delay 10 else 20000000)
|
||||||
|
|
||||||
// every second, print the progress. once it reaches 100%, stop
|
// every second, print the progress. once it reaches 100%, stop
|
||||||
loop {
|
loop {
|
||||||
@ -31,6 +31,6 @@ loop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use await() to get the result from the thread. if the thread is still running, this will block until the thread finishes.
|
// use await() to get the result from the thread. if the thread is still running, this will block until the thread finishes.
|
||||||
result = slow_calculation_thread.await()
|
result := slow_calculation_thread.await()
|
||||||
|
|
||||||
println("Thread finished, result: {0}".format(result))
|
println("Thread finished, result: {0}".format(result))
|
||||||
|
@ -40,8 +40,8 @@ impl SStatementEnum {
|
|||||||
pub struct SStatement {
|
pub struct SStatement {
|
||||||
/// if the statement is a Variable that doesn't exist yet, it will be initialized.
|
/// if the statement is a Variable that doesn't exist yet, it will be initialized.
|
||||||
/// if it's a variable that exists, but is_ref is false, an error may show up: cannot dereference
|
/// if it's a variable that exists, but is_ref is false, an error may show up: cannot dereference
|
||||||
/// NOTE: Maybe add a bool that indicates a variable should be newly declared, shadowing old ones with the same name.
|
/// if the third value is true, the variable will always be initialized, shadowing previous mentions of the same name.
|
||||||
pub output_to: Option<(Box<SStatement>, usize)>,
|
pub output_to: Option<(Box<SStatement>, usize, bool)>,
|
||||||
pub statement: Box<SStatementEnum>,
|
pub statement: Box<SStatementEnum>,
|
||||||
pub force_output_type: Option<VType>,
|
pub force_output_type: Option<VType>,
|
||||||
}
|
}
|
||||||
@ -55,7 +55,12 @@ impl SStatement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn output_to(mut self, statement: SStatement, derefs: usize) -> Self {
|
pub fn output_to(mut self, statement: SStatement, derefs: usize) -> Self {
|
||||||
self.output_to = Some((Box::new(statement), derefs));
|
self.output_to = Some((Box::new(statement), derefs, false));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// like output_to, but always initializes the variable (shadows previous variables of the same name)
|
||||||
|
pub fn initialize_to(mut self, statement: SStatement, derefs: usize) -> Self {
|
||||||
|
self.output_to = Some((Box::new(statement), derefs, true));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
// forces the statement's output to fit in a certain type.
|
// forces the statement's output to fit in a certain type.
|
||||||
@ -248,7 +253,7 @@ impl FormatGs for SStatement {
|
|||||||
form: &mut super::fmtgs::FormatInfo,
|
form: &mut super::fmtgs::FormatInfo,
|
||||||
file: Option<&crate::parsing::file::File>,
|
file: Option<&crate::parsing::file::File>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
if let Some((opt, derefs)) = &self.output_to {
|
if let Some((opt, derefs, is_init)) = &self.output_to {
|
||||||
// TODO!
|
// TODO!
|
||||||
match opt.statement.as_ref() {
|
match opt.statement.as_ref() {
|
||||||
// SStatementEnum::Variable(name, is_ref) => {
|
// SStatementEnum::Variable(name, is_ref) => {
|
||||||
@ -261,7 +266,13 @@ impl FormatGs for SStatement {
|
|||||||
// )?;
|
// )?;
|
||||||
// }
|
// }
|
||||||
_ => {
|
_ => {
|
||||||
write!(f, "{}{} = ", "*".repeat(*derefs), opt.with(info, file))?;
|
write!(
|
||||||
|
f,
|
||||||
|
"{}{} {} ",
|
||||||
|
"*".repeat(*derefs),
|
||||||
|
opt.with(info, file),
|
||||||
|
if *is_init { ":=" } else { "=" }
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,11 @@ pub struct GlobalScriptInfo {
|
|||||||
pub custom_type_names: HashMap<String, usize>,
|
pub custom_type_names: HashMap<String, usize>,
|
||||||
pub custom_types: Vec<VType>,
|
pub custom_types: Vec<VType>,
|
||||||
|
|
||||||
|
/// if true, trying to assign to the reference of a variable that doesn't exist yet will create and initialize that variable.
|
||||||
|
/// if false, variables will only be initialized if this is explicitly stated.
|
||||||
|
/// settings this to true is useful for "x = 2; x = 5;" syntax in parser implementations that don't differenciate initialization and assignment syntactically.
|
||||||
|
pub to_runnable_automatic_initialization: bool,
|
||||||
|
|
||||||
pub formatter: ColorFormatter,
|
pub formatter: ColorFormatter,
|
||||||
|
|
||||||
pub log: Logger,
|
pub log: Logger,
|
||||||
@ -94,6 +99,7 @@ impl Default for GlobalScriptInfo {
|
|||||||
enum_variants: Self::default_enum_variants(),
|
enum_variants: Self::default_enum_variants(),
|
||||||
custom_type_names: HashMap::new(),
|
custom_type_names: HashMap::new(),
|
||||||
custom_types: vec![],
|
custom_types: vec![],
|
||||||
|
to_runnable_automatic_initialization: false,
|
||||||
formatter: Default::default(),
|
formatter: Default::default(),
|
||||||
log: Logger::new(),
|
log: Logger::new(),
|
||||||
}
|
}
|
||||||
|
@ -371,8 +371,9 @@ fn statement_adv(
|
|||||||
}
|
}
|
||||||
SStatementEnum::Variable(v, is_ref) => {
|
SStatementEnum::Variable(v, is_ref) => {
|
||||||
let existing_var = linfo.vars.get(v);
|
let existing_var = linfo.vars.get(v);
|
||||||
|
let is_init_force = if let Some(v) = &to_be_assigned_to { *v.1 } else { false };
|
||||||
// we can't assign to a variable that doesn't exist yet -> create a new one
|
// we can't assign to a variable that doesn't exist yet -> create a new one
|
||||||
if existing_var.is_none() {
|
if is_init_force || (existing_var.is_none() && ginfo.to_runnable_automatic_initialization) {
|
||||||
// if to_be_assigned_to is some (-> this is on the left side of an assignment), create a new variable. else, return an error.
|
// if to_be_assigned_to is some (-> this is on the left side of an assignment), create a new variable. else, return an error.
|
||||||
if let Some((t, is_init)) = to_be_assigned_to {
|
if let Some((t, is_init)) = to_be_assigned_to {
|
||||||
*is_init = true;
|
*is_init = true;
|
||||||
@ -401,7 +402,7 @@ fn statement_adv(
|
|||||||
*is_ref
|
*is_ref
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
return Err(ToRunnableError::UseOfUndefinedVariable(v.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SStatementEnum::FunctionCall(v, args) => {
|
SStatementEnum::FunctionCall(v, args) => {
|
||||||
@ -678,8 +679,9 @@ fn statement_adv(
|
|||||||
return Err(ToRunnableError::StatementRequiresOutputTypeToBeAButItActuallyOutputsBWhichDoesNotFitInA(force_opt.clone(), real_output_type, VType { types: problematic_types }));
|
return Err(ToRunnableError::StatementRequiresOutputTypeToBeAButItActuallyOutputsBWhichDoesNotFitInA(force_opt.clone(), real_output_type, VType { types: problematic_types }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some((opt, derefs)) = &s.output_to {
|
if let Some((opt, derefs, is_init)) = &s.output_to {
|
||||||
let mut is_init = false;
|
// if false, may be changed to true by statement_adv
|
||||||
|
let mut is_init = *is_init;
|
||||||
let optr = statement_adv(
|
let optr = statement_adv(
|
||||||
opt,
|
opt,
|
||||||
ginfo,
|
ginfo,
|
||||||
|
@ -1005,23 +1005,21 @@ pub mod implementation {
|
|||||||
)
|
)
|
||||||
.to()
|
.to()
|
||||||
}
|
}
|
||||||
// 000 =
|
// 000 = :=
|
||||||
(0..=0, Some('=')) => {
|
(0..=0, Some('=')) => {
|
||||||
file.next();
|
file.next();
|
||||||
// NOTE: Old code to change `x = 10` to `&x = 10`
|
|
||||||
// match out.statement.as_mut() {
|
|
||||||
// SStatementEnum::Variable(name, r) => {
|
|
||||||
// if name.starts_with("*") {
|
|
||||||
// *name = name[1..].to_owned();
|
|
||||||
// } else {
|
|
||||||
// *r = true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _ => {}
|
|
||||||
// }
|
|
||||||
// NOTE: Set this 0 to 1 to prevent a = b = c from being valid
|
|
||||||
parse_statement(file)?.output_to(out, 0)
|
parse_statement(file)?.output_to(out, 0)
|
||||||
}
|
}
|
||||||
|
(0..=0, Some(':'))
|
||||||
|
if matches!(
|
||||||
|
file.get_char(file.get_pos().current_char_index + 1),
|
||||||
|
Some('=')
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
file.next();
|
||||||
|
file.next();
|
||||||
|
parse_statement(file)?.initialize_to(out, 0)
|
||||||
|
}
|
||||||
_ => break,
|
_ => break,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user