Oma arsenaalini: PL/I, Limbo, Hollywood, Modula-2 ja Component Pascal.
Jos joku miettii, että miksi PL/I on listallani ja vieläpä ykkösenä, niin mielestäni se ominaisuuksiltaan sopii parhaiten yleiskäyttöiseen ohjelmointityöhön.
Löytyykö muuten PL/I:n lisäksi muista ohjelmointikielistä suoraa tukea bittimerkkijonoille? Yhdistettynä monipuolisiin merkkijononkäsittely ominaisuuksiin, ovat ne omiaan monenlaiseen ongelman ratkaisuun.
Esim. Jos tiedetään päivien lukumäärä vuodessa, päivien lukumäärä kuukausissa ja vuoden ensimmäisen päivän viikonpäivä niin voidaan kalenteri viikkonumero ratkaista mille tahansa päivälle helposti ja nopeasti käyttämättä kalenteria tai apukirjastoja apuna. Esimerkissä päivien lukumäärän ja vuoden ensimmäisen päivän viikonpäivän ratkaisun olen jättänyt PL/I:n tehtäväksi.
Koodi: Valitse kaikki
*PROCESS MARGINS(1, 140);
test: proc options (main);
dcl 1 date_type based,
2 day pic'99',
2 month pic'99',
2 year pic'9999';
dcl d like date_type;
/* fill date structure */
d.day = '01';
d.month = '01';
d.year = '2012';
/* test our proggy */
put skip list (trim(week(d)));
/**************************************************************************************************************************************/
(STRINGRANGE, SUBSCRIPTRANGE):
week: proc (day) returns (fixed bin (31));
dcl day like date_type;
dcl (from, to) like date_type;
dcl (days_from, days_to) fixed bin (31);
dcl total_days fixed bin (31);
dcl week_index fixed bin (31);
dcl weeknro fixed bin (31);
dcl result bit (*) aligned controlled;
dcl weeks (7) bit (7) aligned nonasgn init ('0100000'b, '0010000'b, '0001000'b, '0000100'b, '0000100'b, '0000010'b, '0000001'b);
dcl masks (7) bit (7) aligned nonasgn init ('0111100'b, '1111000'b, '1110001'b, '1100011'b, '1000111'b, '0001111'b, '0011110'b);
dcl bool bit (1);
dcl (days, weekday, tally, substr, lbound, hbound, copy, omitted) builtin;
/* we start from first of january, naturally */
from.day = '01';
from.month = '01';
from.year = day.year;
to = day;
days_from = days(string(from), 'DDMMYYYY');
days_to = days(string(to), 'DDMMYYYY');
/* calculate required length for the bit string */
total_days = days_to - days_from + 1;
if total_days <= 0 then return (0);
/* allocate bit string, holding date range */
allocate result bit (total_days);
/* fill bit string with correct rotation of the week pattern */
week_index = weekday(days_from);
result = copy(weeks(week_index), total_days / 7) || substr(weeks(week_index), 1, mod(total_days, 7));
/* find the number of weeks starting on monday */
weeknro = tally(result, '1'b);
/* free allocated storage */
free result;
/* first week can be partial and if it includes thursday, then add it to the result */
bool = substr(masks(week_index), 1, 1);
If bool then weeknro += 1;
/* maybe first days of the year belong to week numbering of the previous year? */
if weeknro <= 0 then
do;
from.year -= 1;
to = from;
to.day = '31';
to.month = '12';
days_from = days(string(from), 'DDMMYYYY');
days_to = days(string(to), 'DDMMYYYY');
total_days = days_to - days_from + 1;
if total_days <= 0 then return (0);
allocate result bit (total_days);
week_index = weekday(days_from);
result = copy(weeks(week_index), total_days / 7) || substr(weeks(week_index), 1, mod(total_days, 7));
weeknro = tally(result, '1'b);
free result;
end;
return (weeknro);
end week;
/**************************************************************************************************************************************/
end test;