From 0bac3e87b8eb0d2d7322c5cad9a426f45b4f7a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20D=2E=20D=C3=ADaz?= Date: Mon, 13 Nov 2023 02:28:22 +0100 Subject: [PATCH] fix: trash interpreter --- CHANGELOG.md | 9 ++++ README.md | 2 +- src/js/page/trash/argument.mjs | 4 +- src/js/page/trash/constants.mjs | 15 +++--- .../invalid_command_argument_format_error.mjs | 2 +- src/js/page/trash/interpreter.mjs | 48 ++++++++++++++----- 6 files changed, 58 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84c27eb2..f4648146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +**10.4.1** + +``` +IMP: Tests messages + +FIX: Trash: Interpreter (issue #128) +FIX: User input: key up (prev. history) +``` + **10.4.0** ``` diff --git a/README.md b/README.md index f025d8ce..e0440bee 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ Examples: - Create 5000 res.partner: `repeat -t 5000 -c "create -m res.partner -v {name: $(gen str 12 8) + ' (Test)'}" --silent` - Cancel all sale.order: - `$orders = $(search sale.order); repeat -t $orders['length'] -c "call sale.order action_cancel [$orders[$(gen intiter)]['id']]"` + `$orders = $(search sale.order); repeat -t $orders['length'] -c "call sale.order action_cancel [$orders[$repeat_index]['id']]"` #### + Send files diff --git a/src/js/page/trash/argument.mjs b/src/js/page/trash/argument.mjs index f5898a55..b25710d9 100644 --- a/src/js/page/trash/argument.mjs +++ b/src/js/page/trash/argument.mjs @@ -136,7 +136,9 @@ export function validateAndFormatArguments(cmd_def, kwargs) { // Check required const full_kwargs_keys = Object.keys(full_kwargs); - const required_not_set = difference(required_args, full_kwargs_keys); + const required_not_set = difference(required_args, full_kwargs_keys).map( + item => `--${item}`, + ); if (required_not_set.length) { throw new Error( `Required arguments not set! (${required_not_set.join(',')})`, diff --git a/src/js/page/trash/constants.mjs b/src/js/page/trash/constants.mjs index 4e1c221a..589426f9 100644 --- a/src/js/page/trash/constants.mjs +++ b/src/js/page/trash/constants.mjs @@ -29,18 +29,17 @@ export const LEXER = { Positive: 25, }; -export const LEXER_MATH_OPER = new Set([ +export const LEXER_MATH_OPER = [ LEXER.Add, LEXER.Substract, LEXER.Multiply, LEXER.Divide, LEXER.Modulo, LEXER.Pow, -]); +]; -export const LEXERDATA = new Set([ +export const LEXERDATA = [ LEXER.Variable, - LEXER.DataAttribute, LEXER.Runner, LEXER.Array, LEXER.String, @@ -49,6 +48,10 @@ export const LEXERDATA = new Set([ LEXER.Dictionary, LEXER.Boolean, LEXER.Math, +]; + +export const LEXERDATA_EXTENDED = LEXERDATA.concat([ + LEXER.DataAttribute, LEXER.Negative, LEXER.Positive, ]); @@ -195,14 +198,14 @@ export const SYMBOLS = { BLOCK_END: '}', }; -export const SYMBOLS_MATH_OPER = new Set([ +export const SYMBOLS_MATH_OPER = [ SYMBOLS.ADD, SYMBOLS.SUBSTRACT, SYMBOLS.MULTIPLY, SYMBOLS.DIVIDE, SYMBOLS.MODULO, SYMBOLS.POW, -]); +]; export const SYMBOLS_MATH_SIGN = [SYMBOLS.ADD, SYMBOLS.SUBSTRACT]; diff --git a/src/js/page/trash/exceptions/invalid_command_argument_format_error.mjs b/src/js/page/trash/exceptions/invalid_command_argument_format_error.mjs index 2bb65ab5..3c89a385 100644 --- a/src/js/page/trash/exceptions/invalid_command_argument_format_error.mjs +++ b/src/js/page/trash/exceptions/invalid_command_argument_format_error.mjs @@ -3,7 +3,7 @@ export default class extends Error { constructor(message, cmd_name) { - super(message); + super(`${cmd_name}. ${message}`); this.name = 'InvalidCommandArgumentFormatError'; this.cmd_name = cmd_name; } diff --git a/src/js/page/trash/interpreter.mjs b/src/js/page/trash/interpreter.mjs index 3c908df5..961af90e 100644 --- a/src/js/page/trash/interpreter.mjs +++ b/src/js/page/trash/interpreter.mjs @@ -6,6 +6,7 @@ import { KEYWORDS, LEXER, LEXERDATA, + LEXERDATA_EXTENDED, LEXER_MATH_OPER, MATH_OPER_PRIORITIES, SYMBOLS, @@ -112,10 +113,11 @@ export default class Interpreter { if ( options.isData && (char === SYMBOLS.ITEM_DELIMITER || - char === SYMBOLS.DICTIONARY_SEPARATOR) + char === SYMBOLS.DICTIONARY_SEPARATOR || + prev_char === SYMBOLS.ITEM_DELIMITER || + prev_char === SYMBOLS.DICTIONARY_SEPARATOR) ) { do_cut = true; - do_skip = true; } else if ( char === SYMBOLS.EOC || char === SYMBOLS.EOL || @@ -136,8 +138,8 @@ export default class Interpreter { } if (options?.math) { if ( - SYMBOLS_MATH_OPER.has(char) || - SYMBOLS_MATH_OPER.has(prev_char_no_space) + SYMBOLS_MATH_OPER.includes(char) || + SYMBOLS_MATH_OPER.includes(prev_char_no_space) ) { do_cut = true; } @@ -207,7 +209,9 @@ export default class Interpreter { const dtokens = this.tokenize(stoken, {isData: true}); let rstr = ''; for (const tok of dtokens) { - rstr += tok.raw; + if (tok.type !== LEXER.Delimiter) { + rstr += tok.raw; + } } const rsepcount = countBy(rstr, char => char === ':').true; return rsepcount !== sepcount; @@ -233,7 +237,11 @@ export default class Interpreter { ttype = LEXER.ArgumentShort; token_san = token_san.substr(1); } - } else if (token_san === SYMBOLS.EOC) { + } else if ( + token_san === SYMBOLS.EOC || + token_san === SYMBOLS.DICTIONARY_SEPARATOR || + token_san === SYMBOLS.ITEM_DELIMITER + ) { ttype = LEXER.Delimiter; } else if (token_san === SYMBOLS.ASSIGNMENT) { ttype = LEXER.Assignment; @@ -314,13 +322,13 @@ export default class Interpreter { ttype = LEXER.In; } else if (options.math) { if (token_san === SYMBOLS.ADD) { - if (!prev_token_info || LEXER_MATH_OPER.has(prev_token_info[0])) { + if (!prev_token_info || LEXER_MATH_OPER.includes(prev_token_info[0])) { ttype = LEXER.Positive; } else { ttype = LEXER.Add; } } else if (token_san === SYMBOLS.SUBSTRACT) { - if (!prev_token_info || LEXER_MATH_OPER.has(prev_token_info[0])) { + if (!prev_token_info || LEXER_MATH_OPER.includes(prev_token_info[0])) { ttype = LEXER.Negative; } else { ttype = LEXER.Substract; @@ -348,7 +356,7 @@ export default class Interpreter { from = from || 0; const data_tokens = []; const push_token = function (token) { - if (!LEXERDATA.has(token[0])) { + if (!LEXERDATA_EXTENDED.includes(token[0])) { return false; } data_tokens.push(token); @@ -383,7 +391,7 @@ export default class Interpreter { #prioritizer(tokens) { let tokens_no_spaces = tokens.filter(item => item[0] !== LEXER.Space); const tokens_math_oper = tokens_no_spaces.filter(item => - LEXER_MATH_OPER.has(item[0]), + LEXER_MATH_OPER.includes(item[0]), ); if (tokens_math_oper.length <= 1) { return tokens; @@ -490,6 +498,7 @@ export default class Interpreter { arguments: [], inputTokens: [], }; + let num_concats = 0; let sign_cache = null; let last_token_index = -1; let token_subindex = 0; @@ -528,6 +537,7 @@ export default class Interpreter { to_append_eoi.instructions.push( new Instruction(INSTRUCTION_TYPE.CONCAT, index, level), ); + ++num_concats; break; case LEXER.Negative: sign_cache = INSTRUCTION_TYPE.UNITARY_NEGATIVE; @@ -663,7 +673,10 @@ export default class Interpreter { }, ++mlevel, ); - const dindex = parsed_array.inputTokens[0].length; + const dindex = + parsed_array.inputTokens[0].filter(item => + LEXERDATA.includes(item.type), + ).length - parsed_array.unions; res.stack.arguments.push(...parsed_array.stack.arguments); res.stack.values.push(...parsed_array.stack.values); res.stack.names.push(...parsed_array.stack.names); @@ -692,7 +705,11 @@ export default class Interpreter { }, ++mlevel, ); - const dindex = parseInt(parsed_dict.inputTokens[0].length / 2, 10); + let dindex = + parsed_dict.inputTokens[0].filter(item => + LEXERDATA.includes(item.type), + ).length - parsed_dict.unions; + dindex = parseInt(dindex / 2, 10); res.stack.arguments.push(...parsed_dict.stack.arguments); res.stack.values.push(...parsed_dict.stack.values); res.stack.names.push(...parsed_dict.stack.names); @@ -886,7 +903,11 @@ export default class Interpreter { } pushParseData(to_append); - if (index === tokens_len - 1 || !ignore_instr_eoi) { + if ( + index === tokens_len - 1 || + !ignore_instr_eoi || + token.type === LEXER.Delimiter + ) { pushParseData(to_append_eoi); } if (index === tokens_len - 1 || token.type === LEXER.Delimiter) { @@ -908,6 +929,7 @@ export default class Interpreter { return { inputRawString: data, inputTokens: res.inputTokens, + unions: num_concats, stack: { instructions: res.stack.instructions, names: res.stack.names,