✨ add error handling and new parser
class
This commit is contained in:
parent
560746c7b9
commit
8c224b6666
@ -112,15 +112,20 @@
|
||||
|
||||
// parse source code
|
||||
/**/const parse_start = performance.now();
|
||||
juicescript.parse(juice_program);
|
||||
let parse_success = juicescript.parse(juice_program);
|
||||
/**/const parse_end = performance.now();
|
||||
/**/juicescript.io.stderr.info("Parsing took " + (parse_end - parse_start) + "ms");
|
||||
|
||||
// execute program
|
||||
/**/const run_start = performance.now();
|
||||
juicescript.run();
|
||||
/**/const run_end = performance.now();
|
||||
/**/juicescript.io.stderr.info("Running took " + (run_end - run_start) + "ms");
|
||||
if(parse_success){
|
||||
/**/const run_start = performance.now();
|
||||
juicescript.run();
|
||||
/**/const run_end = performance.now();
|
||||
/**/juicescript.io.stderr.info("Running took " + (run_end - run_start) + "ms");
|
||||
|
||||
} else {
|
||||
juicescript.io.stderr.info("Not executing program due to parse error");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
50
src/lexer.js
50
src/lexer.js
@ -25,6 +25,10 @@ class Juicescript_lexer {
|
||||
// token list
|
||||
this.token_list = [];
|
||||
|
||||
// warning and error counter
|
||||
this.warning_count = 0;
|
||||
this.error_count = 0;
|
||||
|
||||
|
||||
// SCAN WHOLE SOURCE //
|
||||
while(!this.is_at_end()){
|
||||
@ -84,7 +88,7 @@ class Juicescript_lexer {
|
||||
|
||||
case "=":
|
||||
if (this.match("=")) this.token_add({type: Juicescript.token_type.EQUAL});
|
||||
else this.warning("unexpected character '" + char + "'");
|
||||
else this.error("unexpected character '" + char + "'");
|
||||
break;
|
||||
|
||||
case "<":
|
||||
@ -127,7 +131,7 @@ class Juicescript_lexer {
|
||||
|
||||
// single slash
|
||||
if(char === "/" && !this.match("/")){
|
||||
this.warning("unexpected character '" + char + "'");
|
||||
this.error("unexpected character '" + char + "'");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -172,8 +176,8 @@ class Juicescript_lexer {
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore with warning
|
||||
this.warning("unexpected character '" + char + "'");
|
||||
// ignore with error
|
||||
this.error("unexpected character '" + char + "'");
|
||||
break;
|
||||
|
||||
|
||||
@ -186,8 +190,8 @@ class Juicescript_lexer {
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore with warning
|
||||
this.warning("unexpected character '" + char + "'");
|
||||
// ignore with error
|
||||
this.error("unexpected character '" + char + "'");
|
||||
break;
|
||||
|
||||
|
||||
@ -205,8 +209,8 @@ class Juicescript_lexer {
|
||||
break;
|
||||
}
|
||||
|
||||
// unexpected
|
||||
this.warning("unexpected character '" + char + "'");
|
||||
// unexpected (ignore with error)
|
||||
this.error("unexpected character '" + char + "'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -239,8 +243,8 @@ class Juicescript_lexer {
|
||||
|
||||
// DID WE REACH THE END OF SOURCE WITHOUT TERMINATION? //
|
||||
if(this.is_at_end()){
|
||||
// ignore with warning
|
||||
this.warning("unterminated string");
|
||||
// ignore with error
|
||||
this.error("unterminated string");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -334,8 +338,8 @@ class Juicescript_lexer {
|
||||
|
||||
// DID WE REACH THE END OF SOURCE WITHOUT TERMINATION? //
|
||||
if(this.is_at_end()){
|
||||
// ignore with warning
|
||||
this.warning("unterminated block comment");
|
||||
// ignore with error
|
||||
this.error("unterminated block comment");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -364,8 +368,8 @@ class Juicescript_lexer {
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore with warning
|
||||
this.warning("unexpected character '" + this.source.charAt(this.start) + "'");
|
||||
// ignore with error
|
||||
this.error("unexpected character '" + this.source.charAt(this.start) + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -539,8 +543,8 @@ class Juicescript_lexer {
|
||||
|
||||
// CHECK IF THERE EVEN IS A NAME //
|
||||
if(flag.length <= 0){
|
||||
// ignore with warning
|
||||
this.warning("unexpected character '" + this.source.charAt(this.start) + "'");
|
||||
// ignore with error
|
||||
this.error("unexpected character '" + this.source.charAt(this.start) + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -679,6 +683,11 @@ class Juicescript_lexer {
|
||||
this.io.stderr.info(text, additional);
|
||||
}
|
||||
warning(text, additional){
|
||||
// KEEP TRACK OF PROBLEM //
|
||||
this.warning_count++;
|
||||
|
||||
|
||||
// PRINT MESSAGE //
|
||||
// add defaults
|
||||
additional ??= {};
|
||||
additional.line ??= this.line;
|
||||
@ -686,12 +695,17 @@ class Juicescript_lexer {
|
||||
// forward
|
||||
this.io.stderr.warning(text, additional);
|
||||
}
|
||||
debug(text, additional){
|
||||
error(text, additional){
|
||||
// KEEP TRACK OF PROBLEM //
|
||||
this.error_count++;
|
||||
|
||||
|
||||
// PRINT MESSAGE //
|
||||
// add defaults
|
||||
additional ??= {};
|
||||
additional.line ??= this.line;
|
||||
|
||||
// forward
|
||||
this.io.stderr.debug(text, additional);
|
||||
this.io.stderr.error(text, additional);
|
||||
}
|
||||
}
|
||||
|
31
src/main.js
31
src/main.js
@ -61,6 +61,10 @@ class Juicescript {
|
||||
Parse given PROGRAM-STRING and store syntax tree
|
||||
*/
|
||||
parse(program_string){
|
||||
// CLEAR OLD PROGRAM TREE //
|
||||
this.program_tree = null;
|
||||
|
||||
|
||||
// DO SCANNING //
|
||||
// get lexer
|
||||
let lexer = new Juicescript_lexer(program_string, {
|
||||
@ -69,10 +73,29 @@ class Juicescript {
|
||||
|
||||
// run lexical analysis
|
||||
let token_list = lexer.scan();
|
||||
/**/for(let one_token of token_list){
|
||||
/**/one_token.type = Juicescript.token_type.name(one_token.type);
|
||||
/**/console.log(one_token);
|
||||
/**/}
|
||||
|
||||
// stop here if unsuccessful
|
||||
if(lexer.error_count > 0) return false;
|
||||
|
||||
|
||||
// GET PROGRAM TREE FROM TOKENS //
|
||||
// get parser
|
||||
let parser = new Juicescript_parser(token_list, {
|
||||
io: this.io
|
||||
});
|
||||
|
||||
// do parsing
|
||||
let program_tree = parser.parse();
|
||||
|
||||
// store program tree
|
||||
this.program_tree = program_tree;
|
||||
|
||||
// stop here if unsuccessful
|
||||
if(parser.error_count > 0) return false;
|
||||
|
||||
|
||||
// RETURN SUCCESS //
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
23
src/parser.js
Normal file
23
src/parser.js
Normal file
@ -0,0 +1,23 @@
|
||||
class Juicescript_parser {
|
||||
/*
|
||||
CONSTRUCTOR: Return new juicescript lexer for SOURCE with OPTIONS
|
||||
*/
|
||||
constructor(token_list, options){
|
||||
// STORE ARGUMENTS //
|
||||
// list of tokens
|
||||
this.token_list = token_list;
|
||||
|
||||
// io adapter
|
||||
this.io = options.io;
|
||||
}
|
||||
|
||||
/*
|
||||
MAIN: Do parsing
|
||||
*/
|
||||
parse(){
|
||||
/**/for(let one_token of this.token_list){
|
||||
/**/one_token.type = Juicescript.token_type.name(one_token.type);
|
||||
/**/console.log(one_token);
|
||||
/**/}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user