petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans
465 lines (400 loc) • 15.1 kB
JavaScript
/**
* PetCareScript Standard Library - Core
* Basic language functions - VERSÃO COMPLETA E CORRIGIDA
*/
const CoreLib = {
// Type conversion functions
toNumber: (value) => {
if (typeof value === 'number') return value;
if (typeof value === 'string') {
const num = parseFloat(value);
if (isNaN(num)) throw new Error('Cannot convert to number');
return num;
}
if (typeof value === 'boolean') return value ? 1 : 0;
if (value instanceof Date) return value.getTime();
throw new Error('Unsupported type for conversion');
},
toString: (value) => {
if (value === null || value === undefined) return 'empty';
if (typeof value === 'string') return value;
if (typeof value === 'boolean') return value ? 'yes' : 'no';
if (typeof value === 'number') {
let text = value.toString();
if (text.endsWith('.0')) {
text = text.substring(0, text.length - 2);
}
return text;
}
if (value instanceof Date) return value.toISOString();
if (Array.isArray(value)) return '[' + value.map(v => CoreLib.toString(v)).join(', ') + ']';
if (typeof value === 'object') return JSON.stringify(value);
return value.toString();
},
toBoolean: (value) => {
if (typeof value === 'boolean') return value;
if (value === null || value === undefined) return false;
if (typeof value === 'number') return value !== 0;
if (typeof value === 'string') return value.length > 0;
if (Array.isArray(value)) return value.length > 0;
if (typeof value === 'object') return Object.keys(value).length > 0;
return true;
},
toArray: (value) => {
if (Array.isArray(value)) return value;
if (typeof value === 'string') return value.split('');
if (typeof value === 'object' && value !== null) return Object.values(value);
return [value];
},
// Type checking
typeOf: (value) => {
if (value === null || value === undefined) return 'empty';
if (Array.isArray(value)) return 'array';
if (value instanceof Date) return 'date';
if (value instanceof RegExp) return 'regex';
return typeof value;
},
isNumber: (value) => typeof value === 'number' && !isNaN(value),
isString: (value) => typeof value === 'string',
isBoolean: (value) => typeof value === 'boolean',
isArray: (value) => Array.isArray(value),
isObject: (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date),
isFunction: (value) => typeof value === 'function' || (value && typeof value.call === 'function'),
isDate: (value) => value instanceof Date,
isNull: (value) => value === null,
isUndefined: (value) => value === undefined,
isEmpty: (value) => {
if (value === null || value === undefined) return true;
if (typeof value === 'string') return value.length === 0;
if (Array.isArray(value)) return value.length === 0;
if (typeof value === 'object' && value !== null) return Object.keys(value).length === 0;
if (typeof value === 'number') return value === 0;
if (typeof value === 'boolean') return !value;
return false;
},
isNaN: (value) => isNaN(value),
isFinite: (value) => isFinite(value),
// Size/length function
size: (value) => {
if (typeof value === 'string') return value.length;
if (Array.isArray(value)) return value.length;
if (typeof value === 'object' && value !== null) {
return Object.keys(value).length;
}
throw new Error('Type does not support size operation');
},
length: (value) => {
if (typeof value === 'string' || Array.isArray(value)) {
return value.length;
}
if (typeof value === 'object' && value !== null) {
return Object.keys(value).length;
}
throw new Error('Value does not support length operation');
},
// Array functions - VERSÃO MELHORADA
push: (array, element) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
array.push(element);
return array;
},
pop: (array) => {
if (!Array.isArray(array)) throw new Error('Argument must be an array');
return array.pop();
},
shift: (array) => {
if (!Array.isArray(array)) throw new Error('Argument must be an array');
return array.shift();
},
unshift: (array, element) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
array.unshift(element);
return array;
},
slice: (array, start = 0, end = null) => {
if (!Array.isArray(array) && typeof array !== 'string') {
throw new Error('First argument must be an array or string');
}
if (end === null) end = array.length;
return array.slice(start, end);
},
splice: (array, start, deleteCount = 0, ...items) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.splice(start, deleteCount, ...items);
},
join: (array, separator = ',') => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.join(separator);
},
indexOf: (array, element) => {
if (!Array.isArray(array) && typeof array !== 'string') {
throw new Error('First argument must be an array or string');
}
return array.indexOf(element);
},
lastIndexOf: (array, element) => {
if (!Array.isArray(array) && typeof array !== 'string') {
throw new Error('First argument must be an array or string');
}
return array.lastIndexOf(element);
},
includes: (array, element) => {
if (!Array.isArray(array) && typeof array !== 'string') {
throw new Error('First argument must be an array or string');
}
return array.includes(element);
},
reverse: (array) => {
if (!Array.isArray(array)) throw new Error('Argument must be an array');
return array.reverse();
},
sort: (array, compareFn = null) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
if (compareFn) {
return array.sort(compareFn);
}
return array.sort();
},
find: (array, predicate) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.find(predicate);
},
findIndex: (array, predicate) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.findIndex(predicate);
},
filter: (array, predicate) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.filter(predicate);
},
map: (array, mapFn) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.map(mapFn);
},
forEach: (array, fn) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
array.forEach(fn);
return null;
},
reduce: (array, reduceFn, initialValue = undefined) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
if (initialValue !== undefined) {
return array.reduce(reduceFn, initialValue);
} else {
return array.reduce(reduceFn);
}
},
concat: (array, ...others) => {
if (!Array.isArray(array)) throw new Error('First argument must be an array');
return array.concat(...others);
},
contains: (haystack, needle) => {
if (typeof haystack === 'string') {
return haystack.includes(needle);
}
if (Array.isArray(haystack)) {
return haystack.includes(needle);
}
if (typeof haystack === 'object' && haystack !== null) {
return haystack.hasOwnProperty(needle);
}
return false;
},
// Object functions - VERSÃO COMPLETA E CORRIGIDA
keys: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.keys(obj);
},
values: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.values(obj);
},
entries: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.entries(obj);
},
hasProperty: (obj, prop) => {
if (typeof obj !== 'object' || obj === null) {
return false;
}
return Object.prototype.hasOwnProperty.call(obj, prop);
},
hasOwnProperty: (obj, prop) => {
if (typeof obj !== 'object' || obj === null) {
return false;
}
return Object.prototype.hasOwnProperty.call(obj, prop);
},
// Object manipulation - VERSÃO MELHORADA
assign: (...args) => {
if (args.length < 1) {
throw new Error('Object.assign requires at least 1 argument');
}
const target = args[0];
const sources = args.slice(1);
if (typeof target !== 'object' || target === null) {
// Se target não é um objeto, retorna uma cópia do primeiro source
if (sources.length > 0 && typeof sources[0] === 'object' && sources[0] !== null) {
return Object.assign({}, ...sources);
}
return {};
}
for (const source of sources) {
if (source !== null && source !== undefined) {
Object.assign(target, source);
}
}
return target;
},
create: (proto, properties = null) => {
const obj = Object.create(proto);
if (properties && typeof properties === 'object') {
Object.assign(obj, properties);
}
return obj;
},
freeze: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.freeze(obj);
},
seal: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.seal(obj);
},
preventExtensions: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.preventExtensions(obj);
},
isFrozen: (obj) => {
if (typeof obj !== 'object' || obj === null) {
return true;
}
return Object.isFrozen(obj);
},
isSealed: (obj) => {
if (typeof obj !== 'object' || obj === null) {
return true;
}
return Object.isSealed(obj);
},
isExtensible: (obj) => {
if (typeof obj !== 'object' || obj === null) {
return false;
}
return Object.isExtensible(obj);
},
getOwnPropertyNames: (obj) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('Argument must be an object');
}
return Object.getOwnPropertyNames(obj);
},
getOwnPropertyDescriptor: (obj, prop) => {
if (typeof obj !== 'object' || obj === null) {
return undefined;
}
return Object.getOwnPropertyDescriptor(obj, prop);
},
defineProperty: (obj, prop, descriptor) => {
if (typeof obj !== 'object' || obj === null) {
throw new Error('First argument must be an object');
}
return Object.defineProperty(obj, prop, descriptor);
},
// JSON functions - VERSÃO MELHORADA
parseJSON: (str) => {
try {
return JSON.parse(str);
} catch (error) {
throw new Error('Invalid JSON: ' + error.message);
}
},
stringifyJSON: (obj, replacer = null, space = null) => {
try {
return JSON.stringify(obj, replacer, space);
} catch (error) {
throw new Error('Cannot stringify to JSON: ' + error.message);
}
},
// String functions - VERSÃO MELHORADA
upper: (str) => {
if (typeof str !== 'string') throw new Error('Argument must be a string');
return str.toUpperCase();
},
lower: (str) => {
if (typeof str !== 'string') throw new Error('Argument must be a string');
return str.toLowerCase();
},
trim: (str) => {
if (typeof str !== 'string') throw new Error('Argument must be a string');
return str.trim();
},
split: (str, separator) => {
if (typeof str !== 'string') throw new Error('First argument must be a string');
return str.split(separator);
},
replace: (str, search, replacement) => {
if (typeof str !== 'string') throw new Error('First argument must be a string');
return str.replace(search, replacement);
},
charAt: (str, index) => {
if (typeof str !== 'string') throw new Error('First argument must be a string');
return str.charAt(index);
},
substring: (str, start, end) => {
if (typeof str !== 'string') throw new Error('First argument must be a string');
return str.substring(start, end);
},
startsWith: (str, prefix) => {
if (typeof str !== 'string') throw new Error('First argument must be a string');
return str.startsWith(prefix);
},
endsWith: (str, suffix) => {
if (typeof str !== 'string') throw new Error('First argument must be a string');
return str.endsWith(suffix);
},
// Input/output functions
read: (message = '') => {
// In Node.js environment would need readline
// For demonstration, using simulated prompt
if (typeof prompt !== 'undefined') {
return prompt(message);
}
return '';
},
write: (...values) => {
console.log(...values.map(v => {
if (v === null) return 'empty';
return v.toString();
}));
},
log: (...args) => {
console.log(...args.map(arg => CoreLib.toString(arg)));
return null;
},
error: (...args) => {
console.error(...args.map(arg => CoreLib.toString(arg)));
return null;
},
warn: (...args) => {
console.warn(...args.map(arg => CoreLib.toString(arg)));
return null;
},
info: (...args) => {
console.info(...args.map(arg => CoreLib.toString(arg)));
return null;
}
};
module.exports = CoreLib;