// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
/// Stub implementation for non-JS backends
/// This file is compiled for wasm, wasm-gc, and native backends
///|
/// Convert Locals to JSON string (stub - same implementation)
/// Converts "true"/"false" to boolean values for proper JS semantics
pub fn locals_to_json(locals : Locals) -> String {
let buf = StringBuilder::new()
buf.write_string("{")
let mut first = true
for k, v in locals.0 {
if not(first) {
buf.write_string(",")
}
first = false
buf.write_string("\"")
buf.write_string(escape_json_string(k))
buf.write_string("\":")
// Convert string booleans to actual booleans
if v == "true" {
buf.write_string("true")
} else if v == "false" {
buf.write_string("false")
} else {
buf.write_string("\"")
buf.write_string(escape_json_string(v))
buf.write_string("\"")
}
}
buf.write_string("}")
buf.to_string()
}
///|
/// Escape special characters for JSON string
fn escape_json_string(s : String) -> String {
let buf = StringBuilder::new()
for c in s {
match c {
'"' => buf.write_string("\\\"")
'\\' => buf.write_string("\\\\")
'\n' => buf.write_string("\\n")
'\r' => buf.write_string("\\r")
'\t' => buf.write_string("\\t")
_ => buf.write_char(c)
}
}
buf.to_string()
}
///|
/// Evaluate an expression - stub implementation for non-JS backends
/// Falls back to simple variable lookup from eval_expression in spec.mbt
pub fn eval_js_expression(expr : String, locals : Locals) -> String {
// On non-JS backends, use the simple expression evaluator
eval_expression(expr, locals)
}
///|
/// Execute a statement - stub implementation for non-JS backends
/// Handles simple "var name = value" patterns only
pub fn exec_js_statement(stmt : String, locals : Locals) -> Unit {
// Try to parse simple "var name = value" pattern
let trimmed = stmt.trim_start(chars=" \t").to_string()
if trimmed.has_prefix("var ") {
let rest = try! trimmed[4:].to_string()
let rest_trimmed = rest.trim_start(chars=" \t").to_string()
// Find variable name
let mut name_end = 0
for c in rest_trimmed {
if c == ' ' || c == '=' {
break
}
name_end += 1
}
if name_end > 0 {
let name = try! rest_trimmed[0:name_end].to_string()
// Find = sign
let after_name = try! rest_trimmed[name_end:].to_string()
let eq_trimmed = after_name.trim_start(chars=" \t").to_string()
if eq_trimmed.has_prefix("=") {
let value_part = try! eq_trimmed[1:].to_string()
let value_trimmed = value_part.trim_start(chars=" \t").to_string()
// Parse value
let value = if value_trimmed.has_prefix("\"") {
// Double-quoted string
parse_quoted_string_stub(value_trimmed, '"')
} else if value_trimmed.has_prefix("'") {
// Single-quoted string
parse_quoted_string_stub(value_trimmed, '\'')
} else {
// Boolean, number, or identifier - take until end or semicolon
let mut end = 0
for c in value_trimmed {
if c == ';' || c == '\n' {
break
}
end += 1
}
try! value_trimmed[0:end].to_string()
}
locals.set(name, value)
return
}
}
}
// Complex statement - not supported on non-JS backends
abort("Complex JavaScript statements are only supported on the JS backend")
}
///|
/// Parse a quoted string, handling escape sequences
fn parse_quoted_string_stub(s : String, quote : Char) -> String {
let chars = s.to_array()
if chars.length() < 2 || chars[0] != quote {
return ""
}
let buf = StringBuilder::new()
let mut i = 1
while i < chars.length() {
let c = chars[i]
if c == quote {
break
} else if c == '\\' && i + 1 < chars.length() {
i += 1
match chars[i] {
'n' => buf.write_char('\n')
't' => buf.write_char('\t')
'r' => buf.write_char('\r')
_ => buf.write_char(chars[i])
}
} else {
buf.write_char(c)
}
i += 1
}
buf.to_string()
}