mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-01-13 07:28:03 -05:00
Start printing diagnostics
This commit is contained in:
@@ -14,6 +14,7 @@ use swc_common::{
|
||||
use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_parser::{Syntax, TsConfig};
|
||||
|
||||
use super::diagnostic::{handle_diagnostics_cli, Diagnostic};
|
||||
use super::expression_compiler::string_literal;
|
||||
use super::function_compiler::{FunctionCompiler, Functionish};
|
||||
use super::name_allocator::NameAllocator;
|
||||
@@ -28,11 +29,13 @@ pub fn command(args: &Vec<String>) {
|
||||
}
|
||||
|
||||
let program = parse(&args[2]);
|
||||
let assembly = compile(&program);
|
||||
let compiler_output = compile(&program);
|
||||
|
||||
handle_diagnostics_cli(&compiler_output.diagnostics);
|
||||
|
||||
let mut file = File::create("out.vsm").expect("Couldn't create out.vsm");
|
||||
|
||||
for line in assembly {
|
||||
for line in compiler_output.assembly {
|
||||
file
|
||||
.write_all(line.as_bytes())
|
||||
.expect("Failed to write line");
|
||||
@@ -82,26 +85,34 @@ pub fn parse(file_path: &String) -> swc_ecma_ast::Program {
|
||||
return result.expect("Parse failed");
|
||||
}
|
||||
|
||||
pub fn compile(program: &swc_ecma_ast::Program) -> Vec<String> {
|
||||
pub struct CompilerOutput {
|
||||
pub diagnostics: Vec<Diagnostic>,
|
||||
pub assembly: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn compile(program: &swc_ecma_ast::Program) -> CompilerOutput {
|
||||
let mut compiler = Compiler::default();
|
||||
compiler.compile_program(&program);
|
||||
|
||||
let mut lines = Vec::<String>::new();
|
||||
let mut assembly = Vec::<String>::new();
|
||||
let mut first = true;
|
||||
|
||||
for def in compiler.definitions {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
lines.push("".to_string());
|
||||
assembly.push("".to_string());
|
||||
}
|
||||
|
||||
for line in def {
|
||||
lines.push(line);
|
||||
assembly.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
return CompilerOutput {
|
||||
diagnostics: compiler.diagnostics,
|
||||
assembly,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn full_compile_raw(source: &str) -> String {
|
||||
@@ -124,13 +135,16 @@ pub fn full_compile_raw(source: &str) -> String {
|
||||
|
||||
let program = result.expect("Parse failed");
|
||||
|
||||
let lines = compile(&program);
|
||||
let compiler_output = compile(&program);
|
||||
|
||||
return lines.join("\n");
|
||||
// TODO: Handle diagnostics
|
||||
|
||||
return compiler_output.assembly.join("\n");
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Compiler {
|
||||
diagnostics: Vec<Diagnostic>,
|
||||
definition_allocator: Rc<RefCell<NameAllocator>>,
|
||||
definitions: Vec<Vec<String>>,
|
||||
}
|
||||
@@ -146,7 +160,8 @@ impl Compiler {
|
||||
}
|
||||
|
||||
fn compile_module(&mut self, module: &swc_ecma_ast::Module) {
|
||||
let scope_analysis = ScopeAnalysis::run(module);
|
||||
let mut scope_analysis = ScopeAnalysis::run(module);
|
||||
self.diagnostics.append(&mut scope_analysis.diagnostics);
|
||||
let scope = init_std_scope();
|
||||
|
||||
use swc_ecma_ast::Decl;
|
||||
|
||||
35
src/vstc/diagnostic.rs
Normal file
35
src/vstc/diagnostic.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
pub enum DiagnosticLevel {
|
||||
Lint,
|
||||
Error,
|
||||
InternalError,
|
||||
}
|
||||
|
||||
pub struct Diagnostic {
|
||||
pub level: DiagnosticLevel,
|
||||
pub message: String,
|
||||
pub span: swc_common::Span,
|
||||
}
|
||||
|
||||
pub fn handle_diagnostics_cli(diagnostics: &Vec<Diagnostic>) {
|
||||
let mut has_error = false;
|
||||
|
||||
for diagnostic in diagnostics {
|
||||
match diagnostic.level {
|
||||
DiagnosticLevel::Lint => {
|
||||
println!("Lint: {}", diagnostic.message);
|
||||
}
|
||||
DiagnosticLevel::Error => {
|
||||
println!("Error: {}", diagnostic.message);
|
||||
has_error = true;
|
||||
}
|
||||
DiagnosticLevel::InternalError => {
|
||||
println!("Internal Error: {}", diagnostic.message);
|
||||
has_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if has_error {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
133
src/vstc/main.rs
133
src/vstc/main.rs
@@ -1,82 +1,79 @@
|
||||
mod assemble;
|
||||
mod run;
|
||||
mod virtual_machine;
|
||||
mod compile;
|
||||
mod scope;
|
||||
mod name_allocator;
|
||||
mod expression_compiler;
|
||||
mod scope_analysis;
|
||||
mod function_compiler;
|
||||
mod capture_finder;
|
||||
mod compile;
|
||||
mod diagnostic;
|
||||
mod expression_compiler;
|
||||
mod function_compiler;
|
||||
mod name_allocator;
|
||||
mod run;
|
||||
mod scope;
|
||||
mod scope_analysis;
|
||||
mod virtual_machine;
|
||||
|
||||
use std::env;
|
||||
use std::process::exit;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
if args.len() < 2 {
|
||||
std::panic!("Not implemented: ValueScript repl");
|
||||
}
|
||||
if args.len() < 2 {
|
||||
std::panic!("Not implemented: ValueScript repl");
|
||||
}
|
||||
|
||||
if args.len() == 2 && (
|
||||
args[1] == "-h" ||
|
||||
args[1] == "--help" ||
|
||||
args[1] == "help"
|
||||
) {
|
||||
show_help();
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() >= 2 && args[1] == "assemble" {
|
||||
assemble::command(&args);
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() >= 2 && args[1] == "run" {
|
||||
run::command(&args);
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() >= 2 && args[1] == "compile" {
|
||||
compile::command(&args);
|
||||
return;
|
||||
}
|
||||
|
||||
println!("ERROR: Unrecognized command\n");
|
||||
if args.len() == 2 && (args[1] == "-h" || args[1] == "--help" || args[1] == "help") {
|
||||
show_help();
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() >= 2 && args[1] == "assemble" {
|
||||
assemble::command(&args);
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() >= 2 && args[1] == "run" {
|
||||
run::command(&args);
|
||||
return;
|
||||
}
|
||||
|
||||
if args.len() >= 2 && args[1] == "compile" {
|
||||
compile::command(&args);
|
||||
return;
|
||||
}
|
||||
|
||||
println!("ERROR: Unrecognized command\n");
|
||||
show_help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fn show_help() {
|
||||
println!("ValueScript toolchain 0.1.0");
|
||||
println!("");
|
||||
println!("USAGE:");
|
||||
println!(" vstc [OPTIONS] [SUBCOMMAND]");
|
||||
println!("");
|
||||
println!("OPTIONS:");
|
||||
println!(" -h, --help");
|
||||
println!(" Print help information");
|
||||
println!("");
|
||||
println!(" -V, --version");
|
||||
println!(" Print version information");
|
||||
println!("");
|
||||
println!("SUBCOMMANDS:");
|
||||
println!(" compile");
|
||||
println!(" Compile an entry point");
|
||||
println!("");
|
||||
println!(" assemble");
|
||||
println!(" Convert assembly to bytecode");
|
||||
println!("");
|
||||
println!(" disassemble");
|
||||
println!(" Convert bytecode to assembly");
|
||||
println!("");
|
||||
println!(" run");
|
||||
println!(" Run a program");
|
||||
println!("");
|
||||
println!(" repl");
|
||||
println!(" Read Eval Print Loop");
|
||||
println!("");
|
||||
println!(" host");
|
||||
println!(" Start database server");
|
||||
println!("ValueScript toolchain 0.1.0");
|
||||
println!("");
|
||||
println!("USAGE:");
|
||||
println!(" vstc [OPTIONS] [SUBCOMMAND]");
|
||||
println!("");
|
||||
println!("OPTIONS:");
|
||||
println!(" -h, --help");
|
||||
println!(" Print help information");
|
||||
println!("");
|
||||
println!(" -V, --version");
|
||||
println!(" Print version information");
|
||||
println!("");
|
||||
println!("SUBCOMMANDS:");
|
||||
println!(" compile");
|
||||
println!(" Compile an entry point");
|
||||
println!("");
|
||||
println!(" assemble");
|
||||
println!(" Convert assembly to bytecode");
|
||||
println!("");
|
||||
println!(" disassemble");
|
||||
println!(" Convert bytecode to assembly");
|
||||
println!("");
|
||||
println!(" run");
|
||||
println!(" Run a program");
|
||||
println!("");
|
||||
println!(" repl");
|
||||
println!(" Read Eval Print Loop");
|
||||
println!("");
|
||||
println!(" host");
|
||||
println!(" Start database server");
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
pub mod virtual_machine;
|
||||
pub mod compile;
|
||||
pub mod run;
|
||||
pub mod scope_analysis;
|
||||
mod scope;
|
||||
mod name_allocator;
|
||||
mod function_compiler;
|
||||
mod expression_compiler;
|
||||
mod capture_finder;
|
||||
mod assemble;
|
||||
mod capture_finder;
|
||||
pub mod compile;
|
||||
pub mod diagnostic;
|
||||
mod expression_compiler;
|
||||
mod function_compiler;
|
||||
mod name_allocator;
|
||||
pub mod run;
|
||||
mod scope;
|
||||
pub mod scope_analysis;
|
||||
pub mod virtual_machine;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
use std::rc::Rc;
|
||||
use std::process::exit;
|
||||
use std::path::Path;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::assemble::assemble;
|
||||
use super::compile::compile;
|
||||
use super::compile::full_compile_raw;
|
||||
use super::compile::parse;
|
||||
use super::compile::compile;
|
||||
use super::virtual_machine::VirtualMachine;
|
||||
use super::diagnostic::handle_diagnostics_cli;
|
||||
use super::virtual_machine::ValTrait;
|
||||
use super::virtual_machine::VirtualMachine;
|
||||
|
||||
pub fn command(args: &Vec<String>) {
|
||||
if args.len() < 3 {
|
||||
@@ -29,7 +30,7 @@ pub fn command(args: &Vec<String>) {
|
||||
let res = format_from_option(&args[argpos]);
|
||||
argpos += 1;
|
||||
res
|
||||
},
|
||||
}
|
||||
_ => format_from_path(&args[argpos]),
|
||||
};
|
||||
|
||||
@@ -66,7 +67,7 @@ fn format_from_option(option: &String) -> RunFormat {
|
||||
"--assembly" => RunFormat::Assembly,
|
||||
"--bytecode" => RunFormat::Bytecode,
|
||||
_ => std::panic!("Unrecognized option {}", option),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn format_from_path(file_path: &String) -> RunFormat {
|
||||
@@ -74,7 +75,7 @@ fn format_from_path(file_path: &String) -> RunFormat {
|
||||
.extension()
|
||||
.and_then(OsStr::to_str)
|
||||
.unwrap_or("");
|
||||
|
||||
|
||||
return match ext {
|
||||
"ts" => RunFormat::TypeScript,
|
||||
"mts" => RunFormat::TypeScript,
|
||||
@@ -90,29 +91,29 @@ fn to_bytecode(format: RunFormat, file_path: &String) -> Rc<Vec<u8>> {
|
||||
return match format {
|
||||
RunFormat::TypeScript => {
|
||||
let ast = parse(file_path);
|
||||
let assembly_lines = compile(&ast);
|
||||
let compiler_output = compile(&ast);
|
||||
handle_diagnostics_cli(&compiler_output.diagnostics);
|
||||
|
||||
let mut assembly = String::new();
|
||||
|
||||
for line in assembly_lines {
|
||||
for line in compiler_output.assembly {
|
||||
assembly.push_str(&line);
|
||||
assembly.push('\n');
|
||||
}
|
||||
|
||||
return assemble(&assembly);
|
||||
},
|
||||
}
|
||||
|
||||
RunFormat::Assembly => {
|
||||
let file_content = std::fs::read_to_string(&file_path)
|
||||
.expect(&std::format!("Failed to read file {}", file_path));
|
||||
|
||||
assemble(&file_content)
|
||||
},
|
||||
}
|
||||
|
||||
RunFormat::Bytecode => Rc::new(
|
||||
std::fs::read(&file_path)
|
||||
.expect(&std::format!("Failed to read file {}", file_path))
|
||||
),
|
||||
RunFormat::Bytecode => {
|
||||
Rc::new(std::fs::read(&file_path).expect(&std::format!("Failed to read file {}", file_path)))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::{cell::RefCell, collections::HashMap, collections::HashSet, rc::Rc};
|
||||
|
||||
use super::diagnostic::{Diagnostic, DiagnosticLevel};
|
||||
use super::scope::Builtin;
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Clone, Debug)]
|
||||
@@ -36,18 +37,6 @@ pub struct Name {
|
||||
captures: Vec<Capture>,
|
||||
}
|
||||
|
||||
enum DiagnosticLevel {
|
||||
Lint,
|
||||
Error,
|
||||
InternalError,
|
||||
}
|
||||
|
||||
pub struct Diagnostic {
|
||||
level: DiagnosticLevel,
|
||||
message: String,
|
||||
span: swc_common::Span,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ScopeAnalysis {
|
||||
pub names: HashMap<NameId, Name>,
|
||||
|
||||
Reference in New Issue
Block a user