importPackage(java.io);
importPackage(java.lang);
//TODO: comment
function getFirstNumberOneBased() {
return 1;
}
/*
This function expects following arguments:
a - some integer number
b - some integer number
It returns arithmetical sum of this two numbers. Note that there are minimum and maximum bound of integers which are representable as JS integers, so this operation may cause overflow.
*/
function sum(a, b) {
//TODO: check if overflow may take place and throw exception
return a + b;
}
/*
This function expects following arguments:
array - instance of Array
It returns magic number representing index of first index in array if array isn't empty.
Calling this function with empty array as an argument leads to undefined behaviour!
*/
function getArrayFromIndex(array) {
return adjustFromOneBasedToZeroBasedNumber(getFirstNumberOneBased());
}
/*
This function expects following arguments:
array - instance of Array
It returns number of items in array.
*/
function getArrayLength(array) {
return array.length;
}
/*
This function expects following arguments:
array - instance of Array
It returns number representing index of last index in array unless array is empty.
Calling this function with empty array as an argument leads to undefined behaviour!
*/
function getArrayToIndex(array) {
return adjustFromOneBasedToZeroBasedNumber(getArrayLength(array));
}
/*
This function expects following arguments:
cond - some boolean value
first - some arbitrary value
second - some arbitrary value
It returns first if "cond" evaluates to boolean value "true", it returns second if "cond" evaluates to boolean value "false". Behaviour isn't defined for other cases.
*/
function conditionalValue(cond, first, second) {
if (cond) {
return first;
}
if (!cond) {
return second;
}
}
/*
This function expects following arguments:
from - some number
isInclusiveFrom - boolean value, which indicate whether "from" value is part of the range or not
to - some number
isInclusiveTo - boolean value, which indicate whether "to" value is part of the range or not
It returns function which accepts single numeric argument and return true if it belongs to specified range and false otherwise.
*/
function inRangeCondition(from, isInclusiveFrom, to, isInclusiveTo) {
return function(value) {
return conditionalValue(((from > value) || (value > to) || ((value == from) && (!isInclusiveFrom)) || ((value == to) && (!isInclusiveTo))), false, true);
}
}
/*
This function expects following arguments:
val - some integer number, which should be less than maximum integer value supported by platform.
It returns val incremented by 1.
*/
function incrementStep(val) {
return sum(val, 1);
}
//TODO: comment
function genericIterate(from, continueCondition, step, func) {
//Unfortunately tails calls aren't optimized in JS :(
/*if (continueCondition(from)) {
func(from);
genericIterate(step(from), continueCondition, step, func);
}*/
var value = from;
while (continueCondition(value)) { //TODO: use conditionalEvaluate function instead of "while" hack
func(value);
value = step(value);
}
}
//TODO: comment
function rangeIterate(from, to, inclusiveTo, func) { //TODO: do we need inclusiveFrom argument?
var cond = inRangeCondition(from, true, to, inclusiveTo); //TODO: explain magic "true" value
genericIterate(from, cond, incrementStep, func);
}
//TODO: comment
function arrayIngicesIterate(array, func) {
rangeIterate(getArrayFromIndex(array), getArrayToIndex(array), true, func); //TODO: explain magic "true" value
}
//TODO: comment
function getArrayItemByIndex(array, index) {
return array[index];
}
//TODO: comment
function arrayValuesIterate(array, func) {
arrayIngicesIterate(array, function(index) {
var arrayItemValue = getArrayItemByIndex(array, index)
func(arrayItemValue);
});
}
//TODO: comment
function createArray() {
return new Array();
}
//TODO: comment
function addItemToTheEndOfArray(array, item) {
return array.push(item);
}
//TODO: comment
function printNumber(number) {
//console.log(number);
print(number);
}
//TODO: comment
function adjustFromOneBasedToZeroBasedNumber(number) {
return sum(number, -1);
}
//TODO: comment
function doBusinessLogic() {
var A = createArray();
rangeIterate(getFirstNumberOneBased(), 368, true, function(value) { //TODO: explain magic "true" value
addItemToTheEndOfArray(A, function() {
printNumber(value);
})
});
//check
arrayValuesIterate(A, function (func) {
func();
});
}
doBusinessLogic();
//TODO: throw exceptions if call contract is violated
//TODO: logging
//TODO: listeners. E.g. beforeGetArrayFromIndex and afterGetArrayFromIndex, et cetera.
//TODO: type annotations
//TODO: move TODO section to the beginning