// SPDX-FileCopyrightText: 2018-2023 Giovanni Dante Grazioli // SPDX-FileCopyrightText: 2018-2019 elicn // SPDX-License-Identifier: BSD-3-Clause import Extra from './extra.js'; import Objects from './objects.js'; import Long from '../long.js'; var _internal_label_cnt = 0; var _internal_variable_cnt = 0; // ---------- inner functions ---------- var parenthesize = function(s) { return ['(', s, ')'].join(''); }; var autoParen = function(s) { return (s.indexOf(' ') > (-1) ? parenthesize(s) : s); }; // ---------- inner objects ---------- var _label = function(name, address) { this.name = name; this.address = address; this.toString = function() { return Global().printer.theme.labels(this.name); }; }; var _func_ptr = function(name, type, args) { this.name = name; this.type = type; this.args = args.map(function(x) { return x.toType ? x.toType() : ('uint' + Global().evars.archbits + '_t'); }); this.toType = function() { return Global().printer.theme.types(this.type) + ' (*)(' + this.args.join(', ') + ')'; }; this.toString = function() { return Global().printer.theme.types(this.type) + ' (*' + Global().printer.auto(this.name) + ')(' + this.args.join(', ') + ')'; }; }; var _ptr = function(name, type, pointer) { this.name = name; this.type = type; this.pointer = pointer; this.toType = function() { return Global().printer.theme.types(this.type) + '*'; }; this.toString = function(define) { if (define) { var suffix = ''; if (this.pointer) { suffix = ' = ' + Global().printer.auto(this.pointer); } return Global().printer.theme.types(this.type) + '* ' + this.name + suffix; } var c = '*('; if (Global().evars.honor.casts) { c += '(' + Global().printer.theme.types(this.type) + '*) '; } return c + Global().printer.auto(autoParen(this.name)) + ')'; }; }; var _local = function(name, type) { this.name = name; this.type = type; this.toType = function() { return Global().printer.theme.types(this.type); }; this.toString = function(define) { if (define) { return Global().printer.theme.types(this.type) + ' ' + Global().printer.auto(this.name); } return Global().printer.auto(this.name); }; }; var _string = function(content) { this.content = content; if (!this.content.startsWith('"') && !this.content.startsWith("'")) { this.content = '"' + this.content; } if (!this.content.endsWith('"') && !this.content.endsWith("'")) { this.content += '"'; } this.content = this.content.replace(/\n/g, '\\n').replace(/\r/g, '\\r'); this.toType = function() { return Global().printer.theme.types('char') + '*'; }; this.toString = function(define) { return define ? null : Global().printer.theme.text(this.content); }; }; var _number = function(content) { this.content = Long.isLong(content) ? ('0x' + content.toString(16)) : content; this.toType = function() { return ''; }; this.toString = function(define) { return define ? null : Global().printer.theme.integers(this.content); }; }; var _macro = function(content) { this.content = content; this.toType = function() { return ''; }; this.toString = function(define) { return define ? null : Global().printer.theme.macro(this.content); }; }; // ------------------------------ export default { uniqueName: function(variable_name) { var n = _internal_variable_cnt++; return [variable_name ? variable_name : "value", n].join('_'); }, newLabel: function(address) { var n = _internal_label_cnt++; return new _label(['label', n].join('_'), address); }, functionPointer: function(variable_name, bits, arguments_type) { return new _func_ptr(variable_name, Extra.to.type(bits || 0), arguments_type || []); }, globalPointer: function(variable_name, ctype_or_bits, is_signed, pointer) { var ctype = Extra.is.number(ctype_or_bits) ? Extra.to.type(ctype_or_bits, is_signed) : ctype_or_bits; return new _ptr(variable_name, ctype, pointer); }, pointer: function(variable_name, ctype_or_bits, is_signed) { var ctype = Extra.is.number(ctype_or_bits) ? Extra.to.type(ctype_or_bits, is_signed) : ctype_or_bits; return new _ptr(variable_name, ctype); }, local: function(variable_name, ctype_or_bits, is_signed) { var ctype = Extra.is.number(ctype_or_bits) ? Extra.to.type(ctype_or_bits, is_signed) : ctype_or_bits; return new _local(variable_name, ctype); }, string: function(string_content) { return new _string(string_content); }, number: function(number) { return new _number(number); }, macro: function(string_content) { return new _macro(string_content); }, object: function(type, args) { return Objects.object(type, args, false); }, newobject: function(type, args) { return Objects.object(type, args, true); }, newarray: function(type, size, init) { return Objects.array(type, size, true, null, init); }, };