Feat: Add string concatenation feature and example

This commit is contained in:
Alvin
2025-09-10 13:31:19 +02:00
parent ece52e4db4
commit ab29612ca8
2 changed files with 151 additions and 6 deletions

View 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

View File

@@ -2,6 +2,14 @@ use std::env;
use std::fs;
use std::collections::HashMap;
#[derive(Debug, Clone)]
struct Function {
name: String,
args: Vec<String>,
body_start: usize,
body_end: usize,
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
@@ -25,10 +33,64 @@ fn main() {
}
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 {
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 mut words = line.split_whitespace();
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 let Some(var_name) = words.next() {
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 {
let mut inner_pc = loop_start;
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;
@@ -144,7 +223,7 @@ fn parse_and_execute(pc: usize, lines: &Vec<&str>, variables: &mut HashMap<Strin
if condition {
let mut inner_pc = if_block_start;
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 {
// 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;
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;
}
@@ -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