wasm.rs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use {
  2. crate::{lexer::tokenize, parser::parse_tokens, program::Program},
  3. serde::Serialize,
  4. serde_wasm_bindgen::to_value,
  5. std::ops::Range,
  6. wasm_bindgen::prelude::*,
  7. };
  8. #[derive(Serialize)]
  9. struct CompileErrorInfo {
  10. error: String,
  11. line: String,
  12. col: String,
  13. }
  14. // Helper function to convert byte span to line/column numbers
  15. fn span_to_line_col(source_code: &str, span: &Range<usize>) -> (usize, usize) {
  16. // Convert byte position to line number (1-based)
  17. let mut line = 1;
  18. let mut current_pos = 0;
  19. for (i, c) in source_code.char_indices() {
  20. if i >= span.start {
  21. break;
  22. }
  23. if c == '\n' {
  24. line += 1;
  25. current_pos = i + 1;
  26. }
  27. }
  28. // Calculate column number (1-based) by finding the start of the line
  29. let column = span.start - current_pos + 1;
  30. (line, column)
  31. }
  32. #[wasm_bindgen]
  33. pub fn assemble(source: &str) -> Result<Vec<u8>, JsValue> {
  34. let tokens = match tokenize(source) {
  35. Ok(tokens) => tokens,
  36. Err(errors) => {
  37. let compile_errors: Vec<CompileErrorInfo> = errors
  38. .iter()
  39. .map(|e| {
  40. let (line, col) = span_to_line_col(source, e.span());
  41. CompileErrorInfo {
  42. error: e.to_string(),
  43. line: line.to_string(),
  44. col: col.to_string(),
  45. }
  46. })
  47. .collect();
  48. return Err(to_value(&compile_errors).unwrap());
  49. }
  50. };
  51. let parse_result = match parse_tokens(&tokens) {
  52. Ok(program) => program,
  53. Err(errors) => {
  54. let compile_errors: Vec<CompileErrorInfo> = errors
  55. .iter()
  56. .map(|e| {
  57. let (line, col) = span_to_line_col(source, e.span());
  58. CompileErrorInfo {
  59. error: e.to_string(),
  60. line: line.to_string(),
  61. col: col.to_string(),
  62. }
  63. })
  64. .collect();
  65. return Err(to_value(&compile_errors).unwrap());
  66. }
  67. };
  68. let program = Program::from_parse_result(parse_result);
  69. let bytecode = program.emit_bytecode();
  70. Ok(bytecode)
  71. }