mirror of
https://github.com/Alvin-Zilverstand/Tralalero_lang.git
synced 2026-03-06 03:06:38 +01:00
Feat: Add string concatenation feature and example
This commit is contained in:
16
examples/string_manipulation.tralla
Normal file
16
examples/string_manipulation.tralla
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// string_manipulation.tralla
|
||||||
|
// This example demonstrates string concatenation.
|
||||||
|
|
||||||
|
let greeting = "Hello";
|
||||||
|
let name = "World";
|
||||||
|
|
||||||
|
Unire Corde full_greeting greeting name;
|
||||||
|
print("Concatenated string:", full_greeting); // Expected: Concatenated string: HelloWorld
|
||||||
|
|
||||||
|
Unire Corde message "This is a " "test.";
|
||||||
|
print("Another concatenated string:", message); // Expected: Another concatenated string: This is a test.
|
||||||
|
|
||||||
|
let space = " ";
|
||||||
|
Unire Corde spaced_greeting greeting space;
|
||||||
|
Unire Corde final_greeting spaced_greeting name;
|
||||||
|
print("Concatenated with space:", final_greeting); // Expected: Concatenated with space: Hello World
|
||||||
141
src/main.rs
141
src/main.rs
@@ -2,6 +2,14 @@ use std::env;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Function {
|
||||||
|
name: String,
|
||||||
|
args: Vec<String>,
|
||||||
|
body_start: usize,
|
||||||
|
body_end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
@@ -25,10 +33,64 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut variables: HashMap<String, String> = HashMap::new();
|
let mut variables: HashMap<String, String> = HashMap::new();
|
||||||
let mut pc = 1; // Program counter starts after "Tralalero Tralala"
|
let mut functions: HashMap<String, Function> = HashMap::new();
|
||||||
|
|
||||||
|
// First pass: collect function definitions
|
||||||
|
let mut pc = 1;
|
||||||
while pc < lines.len() - 1 {
|
while pc < lines.len() - 1 {
|
||||||
pc = parse_and_execute(pc, &lines, &mut variables);
|
let line = lines[pc].trim();
|
||||||
|
let mut words = line.split_whitespace();
|
||||||
|
if let Some(keyword) = words.next() {
|
||||||
|
if keyword == "Lirili" {
|
||||||
|
if let Some(word2) = words.next() {
|
||||||
|
if word2 == "Larila" {
|
||||||
|
if let Some(fn_name) = words.next() {
|
||||||
|
let args_str = words.collect::<Vec<&str>>().join(" ");
|
||||||
|
let args = args_str
|
||||||
|
.trim_start_matches('(')
|
||||||
|
.trim_end_matches(')')
|
||||||
|
.split(',')
|
||||||
|
.map(|s| s.trim().to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let body_start = pc + 2;
|
||||||
|
let mut body_end = body_start;
|
||||||
|
let mut brace_count = 1;
|
||||||
|
|
||||||
|
for i in body_start..lines.len() {
|
||||||
|
if lines[i].trim() == "{" {
|
||||||
|
brace_count += 1;
|
||||||
|
}
|
||||||
|
if lines[i].trim() == "}" {
|
||||||
|
brace_count -= 1;
|
||||||
|
if brace_count == 0 {
|
||||||
|
body_end = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let function = Function {
|
||||||
|
name: fn_name.to_string(),
|
||||||
|
args,
|
||||||
|
body_start,
|
||||||
|
body_end,
|
||||||
|
};
|
||||||
|
functions.insert(fn_name.to_string(), function);
|
||||||
|
pc = body_end + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pc += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass: execute the code
|
||||||
|
pc = 1;
|
||||||
|
while pc < lines.len() - 1 {
|
||||||
|
pc = parse_and_execute(pc, &lines, &mut variables, &functions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,11 +104,28 @@ fn get_value(s: &str, variables: &HashMap<String, String>) -> Option<f64> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<String, String>) -> usize {
|
fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<String, String>, functions: &HashMap<String, Function>) -> usize {
|
||||||
let line = lines[pc].trim();
|
let line = lines[pc].trim();
|
||||||
let mut words = line.split_whitespace();
|
let mut words = line.split_whitespace();
|
||||||
|
|
||||||
if let Some(keyword) = words.next() {
|
if let Some(keyword) = words.next() {
|
||||||
|
if keyword == "Lirili" { // Skip function definitions
|
||||||
|
let mut brace_count = 1;
|
||||||
|
let mut end_pc = pc + 2;
|
||||||
|
for i in (pc + 2)..lines.len() {
|
||||||
|
if lines[i].trim() == "{" {
|
||||||
|
brace_count += 1;
|
||||||
|
}
|
||||||
|
if lines[i].trim() == "}" {
|
||||||
|
brace_count -= 1;
|
||||||
|
if brace_count == 0 {
|
||||||
|
end_pc = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return end_pc + 1;
|
||||||
|
}
|
||||||
if keyword == "Biscottini" {
|
if keyword == "Biscottini" {
|
||||||
if let Some(var_name) = words.next() {
|
if let Some(var_name) = words.next() {
|
||||||
let value = words.collect::<Vec<&str>>().join(" ");
|
let value = words.collect::<Vec<&str>>().join(" ");
|
||||||
@@ -87,7 +166,7 @@ fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<Strin
|
|||||||
for _ in 0..times {
|
for _ in 0..times {
|
||||||
let mut inner_pc = loop_start;
|
let mut inner_pc = loop_start;
|
||||||
while inner_pc < loop_end {
|
while inner_pc < loop_end {
|
||||||
inner_pc = parse_and_execute(inner_pc, lines, variables);
|
inner_pc = parse_and_execute(inner_pc, lines, variables, functions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loop_end + 1;
|
return loop_end + 1;
|
||||||
@@ -144,7 +223,7 @@ fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<Strin
|
|||||||
if condition {
|
if condition {
|
||||||
let mut inner_pc = if_block_start;
|
let mut inner_pc = if_block_start;
|
||||||
while inner_pc < if_block_end {
|
while inner_pc < if_block_end {
|
||||||
inner_pc = parse_and_execute(inner_pc, lines, variables);
|
inner_pc = parse_and_execute(inner_pc, lines, variables, functions);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check for an else block
|
// Check for an else block
|
||||||
@@ -171,7 +250,7 @@ fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<Strin
|
|||||||
|
|
||||||
let mut inner_pc = else_block_start;
|
let mut inner_pc = else_block_start;
|
||||||
while inner_pc < else_block_end {
|
while inner_pc < else_block_end {
|
||||||
inner_pc = parse_and_execute(inner_pc, lines, variables);
|
inner_pc = parse_and_execute(inner_pc, lines, variables, functions);
|
||||||
}
|
}
|
||||||
next_pc = else_block_end + 1;
|
next_pc = else_block_end + 1;
|
||||||
}
|
}
|
||||||
@@ -182,6 +261,56 @@ fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<Strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if keyword == "Unire" { // New: String Concatenation
|
||||||
|
if let (Some(word2), Some(result_var), Some(str1_val), Some(str2_val)) = (words.next(), words.next(), words.next(), words.next()) {
|
||||||
|
if word2 == "Corde" {
|
||||||
|
let s1 = if str1_val.starts_with('"') && str1_val.ends_with('"') {
|
||||||
|
str1_val.trim_matches('"').to_string()
|
||||||
|
} else if let Some(val) = variables.get(str1_val) {
|
||||||
|
val.clone()
|
||||||
|
} else {
|
||||||
|
"".to_string() // Handle undefined variable or invalid string
|
||||||
|
};
|
||||||
|
|
||||||
|
let s2 = if str2_val.starts_with('"') && str2_val.ends_with('"') {
|
||||||
|
str2_val.trim_matches('"').to_string()
|
||||||
|
} else if let Some(val) = variables.get(str2_val) {
|
||||||
|
val.clone()
|
||||||
|
} else {
|
||||||
|
"".to_string() // Handle undefined variable or invalid string
|
||||||
|
};
|
||||||
|
|
||||||
|
variables.insert(result_var.to_string(), format!("{}{}", s1, s2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pc + 1;
|
||||||
|
} else if keyword == "Trippi" {
|
||||||
|
if let Some(word2) = words.next() {
|
||||||
|
if word2 == "Troppi" {
|
||||||
|
if let Some(fn_call_str) = words.next() {
|
||||||
|
let parts: Vec<&str> = fn_call_str.splitn(2, '(').collect();
|
||||||
|
if parts.len() == 2 {
|
||||||
|
let fn_name = parts[0];
|
||||||
|
if let Some(function) = functions.get(fn_name).cloned() {
|
||||||
|
let args_str = parts[1].trim_end_matches(')');
|
||||||
|
let arg_values: Vec<&str> = args_str.split(',').map(|s| s.trim()).collect();
|
||||||
|
|
||||||
|
let mut local_vars = variables.clone();
|
||||||
|
for (i, arg_name) in function.args.iter().enumerate() {
|
||||||
|
if let Some(arg_value) = arg_values.get(i) {
|
||||||
|
local_vars.insert(arg_name.clone(), arg_value.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut inner_pc = function.body_start;
|
||||||
|
while inner_pc < function.body_end {
|
||||||
|
inner_pc = parse_and_execute(inner_pc, lines, &mut local_vars, functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pc + 1
|
pc + 1
|
||||||
|
|||||||
Reference in New Issue
Block a user