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