2019-02-04 21:16:35 +01:00
|
|
|
|
#include <string.h>
|
2019-02-13 12:09:35 +01:00
|
|
|
|
#include <stdio.h>
|
2019-02-10 22:21:20 +01:00
|
|
|
|
#include <stdlib.h>
|
2019-02-18 01:17:47 +01:00
|
|
|
|
#include <wchar.h>
|
2019-02-04 21:16:35 +01:00
|
|
|
|
|
2019-01-19 14:42:56 +01:00
|
|
|
|
#include "util.h"
|
2019-02-18 01:17:47 +01:00
|
|
|
|
#include "read.h"
|
2019-01-22 00:08:27 +01:00
|
|
|
|
#include "eval.h"
|
2019-02-18 01:17:47 +01:00
|
|
|
|
#include "print.h"
|
2019-01-19 14:42:56 +01:00
|
|
|
|
|
2019-01-29 00:07:33 +01:00
|
|
|
|
int allNums(object list)
|
2019-02-10 22:21:20 +01:00
|
|
|
|
/* проверава да ли је објекат листа чији је сваки члан број, претпоставља да је
|
|
|
|
|
* објекат валидна листа */
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
|
|
|
|
object *currentCell = &list;
|
|
|
|
|
while (TYPE(*currentCell) != nilObject)
|
|
|
|
|
{
|
|
|
|
|
if (TYPE(CAR(*currentCell)) != numberObject)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
currentCell = &CDR(*currentCell);
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-28 23:43:33 +01:00
|
|
|
|
int allStrings(object list)
|
|
|
|
|
{
|
|
|
|
|
object *currentCell = &list;
|
|
|
|
|
while (TYPE(*currentCell) != nilObject)
|
|
|
|
|
{
|
|
|
|
|
if (TYPE(CAR(*currentCell)) != stringObject)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
currentCell = &CDR(*currentCell);
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-29 00:07:33 +01:00
|
|
|
|
int allSyms(object list)
|
2019-02-10 22:21:20 +01:00
|
|
|
|
/* проверава да ли је дати објекат симбол, или листа (правилна или крња), чији
|
|
|
|
|
* је сваки члан симбол */
|
2019-01-29 00:07:33 +01:00
|
|
|
|
{
|
|
|
|
|
object *currentCell = &list;
|
2019-02-10 22:21:20 +01:00
|
|
|
|
while (TYPE(*currentCell) == consObject)
|
2019-01-29 00:07:33 +01:00
|
|
|
|
{
|
|
|
|
|
if (TYPE(CAR(*currentCell)) != symbolObject)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
currentCell = &CDR(*currentCell);
|
|
|
|
|
}
|
2019-02-10 22:21:20 +01:00
|
|
|
|
switch (TYPE(*currentCell))
|
|
|
|
|
{
|
|
|
|
|
case symbolObject:
|
|
|
|
|
case nilObject:
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object addInt(object parameters)
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = numberObject;
|
|
|
|
|
|
2019-01-29 00:07:33 +01:00
|
|
|
|
if (!allNums(parameters))
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 0)
|
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = longlongToNumber(0LL);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
object first, rest;
|
|
|
|
|
first = CAR(parameters);
|
2019-02-09 14:06:53 +01:00
|
|
|
|
rest = addInt(CDR(parameters));
|
2019-01-19 14:42:56 +01:00
|
|
|
|
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = plusNum(first, rest);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object subtractInt(object parameters)
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = numberObject;
|
|
|
|
|
|
2019-01-29 00:07:33 +01:00
|
|
|
|
if (!allNums(parameters))
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 0)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 1)
|
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = minusNum(CAR(parameters));
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = plusNum(CAR(parameters),
|
2019-02-09 14:06:53 +01:00
|
|
|
|
minusNum(addInt(CDR(parameters))));
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object multiplyInt(object parameters)
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = numberObject;
|
|
|
|
|
|
2019-01-29 00:07:33 +01:00
|
|
|
|
if (!allNums(parameters))
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 0)
|
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = longlongToNumber(1LL);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
object first, rest;
|
|
|
|
|
first = CAR(parameters);
|
2019-02-09 14:06:53 +01:00
|
|
|
|
rest = multiplyInt(CDR(parameters));
|
2019-01-19 14:42:56 +01:00
|
|
|
|
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = timesNum(first,rest);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object divideInt(object parameters)
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = numberObject;
|
|
|
|
|
|
2019-01-29 00:07:33 +01:00
|
|
|
|
if (!allNums(parameters))
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 0)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 1)
|
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = inverseNum(CAR(parameters));
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object check = inverseNum(multiplyInt(CDR(parameters)));
|
2019-01-20 23:48:12 +01:00
|
|
|
|
if (TYPE(check) != errorObject)
|
2019-01-19 14:42:56 +01:00
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = timesNum(CAR(parameters),
|
2019-02-09 14:06:53 +01:00
|
|
|
|
inverseNum(multiplyInt(CDR(parameters))));
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = check;
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
2019-01-20 23:48:12 +01:00
|
|
|
|
result = shortenFractionNum(result);
|
2019-01-19 14:42:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2019-01-19 20:30:52 +01:00
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object exactToInexactInt(object parameters)
|
2019-01-21 18:44:56 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-21 18:44:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (TYPE(CAR(parameters)) != numberObject)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-21 18:44:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = exactToInexactNum(CAR(parameters));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object inexactToExactInt(object parameters)
|
2019-01-21 18:44:56 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-21 18:44:56 +01:00
|
|
|
|
}
|
|
|
|
|
else if (TYPE(CAR(parameters)) != numberObject)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-21 18:44:56 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = inexactToExactNum(CAR(parameters));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-19 09:49:55 +01:00
|
|
|
|
object fractionPart(object parameters, int part)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (TYPE(CAR(parameters)) != numberObject ||
|
|
|
|
|
NUM_TYPE(CAR(parameters)) != fractionNum)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = numberObject;
|
|
|
|
|
NUM_TYPE(result) = fractionNum;
|
|
|
|
|
NUM_DENOM(result) = 1;
|
|
|
|
|
NUM_NUMER(result) = !part ? NUM_NUMER(CAR(parameters)) :
|
|
|
|
|
NUM_DENOM(CAR(parameters));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object numeratorInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return fractionPart(parameters, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object denominatorInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return fractionPart(parameters, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object quoteInt(object parameters)
|
2019-01-19 20:30:52 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-19 20:30:52 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = copyObject(CAR(parameters));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2019-01-22 00:08:27 +01:00
|
|
|
|
|
2019-02-04 21:16:35 +01:00
|
|
|
|
int validArgumentList(object list)
|
|
|
|
|
{
|
2019-02-10 22:21:20 +01:00
|
|
|
|
if (!allSyms(list))
|
2019-02-04 21:16:35 +01:00
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int allUniqueSyms = 1;
|
|
|
|
|
object *currentSymbol1 = &list;
|
2019-02-10 22:21:20 +01:00
|
|
|
|
while (TYPE(*currentSymbol1) == consObject)
|
2019-02-04 21:16:35 +01:00
|
|
|
|
{
|
|
|
|
|
object *currentSymbol2 = &CDR(*currentSymbol1);
|
2019-02-10 22:21:20 +01:00
|
|
|
|
while (TYPE(*currentSymbol2) == consObject)
|
2019-02-04 21:16:35 +01:00
|
|
|
|
{
|
|
|
|
|
if (!strcmp(SYM(CAR(*currentSymbol1)),
|
|
|
|
|
SYM(CAR(*currentSymbol2))))
|
|
|
|
|
{
|
|
|
|
|
allUniqueSyms = 0;
|
|
|
|
|
goto breakloop;
|
|
|
|
|
}
|
|
|
|
|
currentSymbol2 = &CDR(*currentSymbol2);
|
|
|
|
|
}
|
2019-02-10 22:21:20 +01:00
|
|
|
|
if (TYPE(*currentSymbol2) == symbolObject &&
|
|
|
|
|
!strcmp(SYM(*currentSymbol2),
|
|
|
|
|
SYM(CAR(*currentSymbol1))))
|
|
|
|
|
{
|
|
|
|
|
allUniqueSyms = 0;
|
|
|
|
|
goto breakloop;
|
|
|
|
|
}
|
2019-02-04 21:16:35 +01:00
|
|
|
|
currentSymbol1 = &CDR(*currentSymbol1);
|
|
|
|
|
}
|
|
|
|
|
breakloop:
|
|
|
|
|
return allUniqueSyms;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object lambdaInt(object parameters, env currentEnv)
|
2019-01-29 00:07:33 +01:00
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) < 2)
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
2019-02-04 21:16:35 +01:00
|
|
|
|
else if (!validArgumentList(CAR(parameters)))
|
2019-01-29 00:07:33 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TYPE(result) = procedureObject;
|
|
|
|
|
PROC(result) = createProcedure();
|
|
|
|
|
PROC_TYPE(result) = compoundProc;
|
2019-02-13 12:09:35 +01:00
|
|
|
|
PROC_SPECIAL(result) = 0;
|
2019-01-29 00:07:33 +01:00
|
|
|
|
PROC_COMP_ARGS(result) = copyObject(CAR(parameters));
|
|
|
|
|
PROC_COMP_BODY(result) = copyObject(CDR(parameters));
|
2019-02-05 16:35:05 +01:00
|
|
|
|
PROC_COMP_ENV(result) = currentEnv;
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object defineInt(object parameters, env currentEnv)
|
2019-01-22 00:08:27 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object result, value;
|
2019-01-29 00:07:33 +01:00
|
|
|
|
if (listLength(parameters) == 0)
|
2019-01-22 00:08:27 +01:00
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-22 00:08:27 +01:00
|
|
|
|
}
|
|
|
|
|
else if (TYPE(CAR(parameters)) == symbolObject)
|
|
|
|
|
{
|
2019-01-29 00:07:33 +01:00
|
|
|
|
if (listLength(parameters) == 2)
|
|
|
|
|
{
|
|
|
|
|
result = copyObject(CAR(parameters));
|
2019-02-19 09:49:55 +01:00
|
|
|
|
value = Eval(copyObject(CAR(CDR(parameters))),
|
2019-02-09 14:06:53 +01:00
|
|
|
|
currentEnv);
|
|
|
|
|
if (TYPE(value) == errorObject)
|
|
|
|
|
{
|
2019-02-18 23:20:44 +01:00
|
|
|
|
CPYERR(ERR(value));
|
2019-02-09 14:06:53 +01:00
|
|
|
|
}
|
|
|
|
|
addSymbolVariable(SYM(result), value, currentEnv);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (TYPE(CAR(parameters)) == consObject)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) >= 2)
|
|
|
|
|
{
|
|
|
|
|
if (allSyms(CAR(parameters)))
|
|
|
|
|
{
|
|
|
|
|
result = copyObject(CAR(CAR(parameters)));
|
|
|
|
|
object args = copyObject(CDR(CAR(parameters)));
|
|
|
|
|
deleteObject(CAR(parameters));
|
|
|
|
|
CAR(parameters) = copyObject(args);
|
|
|
|
|
deleteObject(args);
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object proc = lambdaInt(parameters,
|
|
|
|
|
currentEnv);
|
2019-02-05 16:35:05 +01:00
|
|
|
|
addSymbolVariable(SYM(result), proc,
|
|
|
|
|
currentEnv);
|
2019-03-23 14:10:16 +01:00
|
|
|
|
deleteObject(proc);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(argumentNumberError);
|
2019-01-29 00:07:33 +01:00
|
|
|
|
}
|
2019-01-22 00:08:27 +01:00
|
|
|
|
}
|
2019-01-27 16:31:32 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-09 14:06:53 +01:00
|
|
|
|
SIGERR(typeError);
|
2019-01-27 16:31:32 +01:00
|
|
|
|
}
|
2019-01-22 00:08:27 +01:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
|
2019-02-13 12:09:35 +01:00
|
|
|
|
object defineMacroInt(object parameters, env currentEnv)
|
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) < 2)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
else if (TYPE(CAR(parameters)) != consObject)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (allSyms(CAR(parameters)))
|
|
|
|
|
{
|
|
|
|
|
result = copyObject(CAR(CAR(parameters)));
|
|
|
|
|
object args = copyObject(CDR(CAR(parameters)));
|
|
|
|
|
deleteObject(CAR(parameters));
|
|
|
|
|
CAR(parameters) = copyObject(args);
|
|
|
|
|
deleteObject(args);
|
|
|
|
|
object proc = lambdaInt(parameters, currentEnv);
|
|
|
|
|
PROC_SPECIAL(proc) = 1;
|
|
|
|
|
addSymbolVariable(SYM(result), proc, currentEnv);
|
2019-03-23 14:10:16 +01:00
|
|
|
|
deleteObject(proc);
|
2019-02-13 12:09:35 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object cmpMultiple(object parameters, int flag)
|
|
|
|
|
/* проверава помоћу cmp функције у util.h хедеру, да ли је дата листа, листа
|
|
|
|
|
* строго опадајућих, једнаких, или строго растућих бројева, у зависности од
|
|
|
|
|
* тога да ли је "flag" 1, 0 или -1 респективно */
|
2019-02-07 23:07:02 +01:00
|
|
|
|
{
|
|
|
|
|
if (!allNums(parameters))
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (listLength(parameters) == 0 || listLength(parameters) == 1)
|
|
|
|
|
{
|
|
|
|
|
return intToBool(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int resultInt = 1;
|
|
|
|
|
object *current = ¶meters;
|
|
|
|
|
while (TYPE(CDR(*current)) != nilObject)
|
|
|
|
|
{
|
2019-02-10 22:21:20 +01:00
|
|
|
|
if (cmp(CAR(*current), CAR(CDR(*current))) != flag)
|
2019-02-07 23:07:02 +01:00
|
|
|
|
{
|
|
|
|
|
resultInt = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
current = &CDR(*current);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = boolObject;
|
|
|
|
|
BOOL(result) = resultInt;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object lessInt(object parameters)
|
2019-02-07 23:07:02 +01:00
|
|
|
|
{
|
2019-02-10 22:21:20 +01:00
|
|
|
|
return cmpMultiple(parameters, -1);
|
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object eqNumInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return cmpMultiple(parameters, 0);
|
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object greaterInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return cmpMultiple(parameters, 1);
|
2019-02-07 23:07:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 14:06:53 +01:00
|
|
|
|
object ifInt(object parameters, env currentEnv)
|
2019-02-07 23:07:02 +01:00
|
|
|
|
{
|
|
|
|
|
object predicate, result;
|
|
|
|
|
switch (listLength(parameters))
|
|
|
|
|
{
|
|
|
|
|
case 2:
|
2019-02-19 09:49:55 +01:00
|
|
|
|
predicate = Eval(copyObject(CAR(parameters)), currentEnv);
|
2019-02-09 14:06:53 +01:00
|
|
|
|
if (TYPE(predicate) == errorObject)
|
|
|
|
|
{
|
2019-02-18 23:20:44 +01:00
|
|
|
|
CPYERR(ERR(predicate));
|
2019-02-09 14:06:53 +01:00
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
|
|
|
|
|
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
|
|
|
|
{
|
2019-02-10 22:21:20 +01:00
|
|
|
|
TYPE(result) = nilObject;
|
2019-02-07 23:07:02 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-19 09:49:55 +01:00
|
|
|
|
result = Eval(copyObject(CAR(CDR(parameters))),
|
2019-02-07 23:07:02 +01:00
|
|
|
|
currentEnv);
|
|
|
|
|
}
|
2019-02-09 14:06:53 +01:00
|
|
|
|
|
|
|
|
|
if (TYPE(result) == errorObject)
|
|
|
|
|
{
|
2019-02-18 23:20:44 +01:00
|
|
|
|
CPYERR(ERR(result));
|
2019-02-09 14:06:53 +01:00
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
break;
|
|
|
|
|
case 3:
|
2019-02-19 09:49:55 +01:00
|
|
|
|
predicate = Eval(copyObject(CAR(parameters)), currentEnv);
|
2019-02-09 14:06:53 +01:00
|
|
|
|
if (TYPE(predicate) == errorObject)
|
|
|
|
|
{
|
2019-02-18 23:20:44 +01:00
|
|
|
|
CPYERR(ERR(predicate));
|
2019-02-09 14:06:53 +01:00
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
|
|
|
|
|
if (TYPE(predicate) == boolObject && BOOL(predicate) == 0)
|
|
|
|
|
{
|
2019-02-19 09:49:55 +01:00
|
|
|
|
result = Eval(copyObject(CAR(CDR(CDR(parameters)))),
|
2019-02-07 23:07:02 +01:00
|
|
|
|
currentEnv);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-02-19 09:49:55 +01:00
|
|
|
|
result = Eval(copyObject(CAR(CDR(parameters))),
|
2019-02-07 23:07:02 +01:00
|
|
|
|
currentEnv);
|
|
|
|
|
}
|
2019-02-09 14:06:53 +01:00
|
|
|
|
|
|
|
|
|
if (TYPE(result) == errorObject)
|
|
|
|
|
{
|
2019-02-18 23:20:44 +01:00
|
|
|
|
CPYERR(ERR(result));
|
2019-02-09 14:06:53 +01:00
|
|
|
|
}
|
2019-02-07 23:07:02 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2019-02-10 22:21:20 +01:00
|
|
|
|
|
|
|
|
|
object checkType(object parameters, dataType type)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = boolObject;
|
|
|
|
|
BOOL(result) = (type == TYPE(CAR(parameters)));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object nilQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, nilObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object consQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, consObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object numberQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, numberObject);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-19 09:49:55 +01:00
|
|
|
|
object checkNumType(object parameters, numType type)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = boolObject;
|
|
|
|
|
BOOL(result) = TYPE(CAR(parameters)) == numberObject &&
|
|
|
|
|
(NUM_TYPE(CAR(parameters)) == type ? 1 : 0);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object fractionQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkNumType(parameters, fractionNum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object realQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkNumType(parameters, realNum);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object symbolQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, symbolObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object procedureQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, procedureObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object boolQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, boolObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object stringQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, stringObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object charQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return checkType(parameters, charObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object listQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = boolObject;
|
|
|
|
|
BOOL(result) = properList(CAR(parameters));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-18 01:17:47 +01:00
|
|
|
|
int validAppendArgs(object parameters)
|
|
|
|
|
{
|
|
|
|
|
int length = listLength(parameters);
|
|
|
|
|
if (length == 0 || length == 1)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else if (!properList(CAR(parameters)))
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return validAppendArgs(CDR(parameters));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object appendAux(object parameters)
|
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) == 0)
|
|
|
|
|
{
|
|
|
|
|
TYPE(result) = nilObject;
|
|
|
|
|
}
|
|
|
|
|
else if (listLength(parameters) == 1)
|
|
|
|
|
{
|
|
|
|
|
result = copyObject(CAR(parameters));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
object rest = appendAux(CDR(parameters));
|
|
|
|
|
result = copyObject(CAR(parameters));
|
|
|
|
|
object *end = &result;
|
|
|
|
|
while (TYPE(*end) != nilObject)
|
|
|
|
|
{
|
|
|
|
|
end = &CDR(*end);
|
|
|
|
|
}
|
|
|
|
|
*end = rest;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object appendInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (!validAppendArgs(parameters))
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
return appendAux(parameters);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object consInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 2)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = consObject;
|
|
|
|
|
CONS(result) = malloc(sizeof(cons));
|
|
|
|
|
CAR(result) = copyObject(CAR(parameters));
|
|
|
|
|
CDR(result) = copyObject(CAR(CDR(parameters)));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-11 11:21:30 +01:00
|
|
|
|
object cellElement(object parameters, int part)
|
|
|
|
|
/* враћа car или cdr (сар или сдр) датог конс објекта у зависности од тога да
|
|
|
|
|
* ли је part 0 или нешто друго (1) */
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (TYPE(CAR(parameters)) != consObject)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
return !part ? copyObject(CAR(CAR(parameters))) :
|
|
|
|
|
copyObject(CDR(CAR(parameters)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object carInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return cellElement(parameters, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object cdrInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
return cellElement(parameters, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object eqvQInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 2)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = boolObject;
|
2019-02-11 11:21:30 +01:00
|
|
|
|
BOOL(result) = 1;
|
2019-02-10 22:21:20 +01:00
|
|
|
|
if (TYPE(CAR(parameters)) != TYPE(CAR(CDR(parameters))))
|
|
|
|
|
{
|
|
|
|
|
BOOL(result) = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
switch (TYPE(CAR(parameters)))
|
|
|
|
|
{
|
|
|
|
|
case numberObject:
|
|
|
|
|
if (NUM_TYPE(CAR(parameters)) !=
|
|
|
|
|
NUM_TYPE(CAR(CDR(parameters))))
|
|
|
|
|
{
|
|
|
|
|
BOOL(result) = 0;
|
|
|
|
|
}
|
|
|
|
|
switch (NUM_TYPE(CAR(parameters)))
|
|
|
|
|
{
|
|
|
|
|
case fractionNum:
|
|
|
|
|
BOOL(result) = NUM_NUMER(CAR(parameters)) ==
|
|
|
|
|
NUM_NUMER(CAR(CDR(parameters))) &&
|
|
|
|
|
NUM_DENOM(CAR(parameters)) ==
|
|
|
|
|
NUM_DENOM(CAR(CDR(parameters)));
|
|
|
|
|
break;
|
|
|
|
|
case realNum:
|
|
|
|
|
BOOL(result) = NUM_REAL(CAR(parameters)) ==
|
|
|
|
|
NUM_REAL(CAR(CDR(parameters)));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case symbolObject:
|
|
|
|
|
BOOL(result) = !strcmp(SYM(CAR(parameters)),
|
|
|
|
|
SYM(CAR(CDR(parameters))));
|
|
|
|
|
break;
|
|
|
|
|
case boolObject:
|
|
|
|
|
BOOL(result) = !BOOL(CAR(parameters)) ==
|
|
|
|
|
!BOOL(CAR(CDR(parameters)));
|
|
|
|
|
break;
|
|
|
|
|
case stringObject:
|
|
|
|
|
BOOL(result) = !strcmp(STR(CAR(parameters)),
|
|
|
|
|
STR(CAR(CDR(parameters))));
|
|
|
|
|
break;
|
|
|
|
|
case charObject:
|
2019-02-10 22:33:16 +01:00
|
|
|
|
BOOL(result) = CHR(CAR(parameters)) ==
|
|
|
|
|
CHR(CAR(CDR(parameters)));
|
2019-02-10 22:21:20 +01:00
|
|
|
|
break;
|
2019-02-11 11:21:30 +01:00
|
|
|
|
case nilObject:
|
|
|
|
|
BOOL(result) = 1;
|
|
|
|
|
break;
|
2019-02-10 22:21:20 +01:00
|
|
|
|
case consObject:
|
|
|
|
|
case procedureObject:
|
|
|
|
|
default:
|
|
|
|
|
BOOL(result) = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2019-02-11 11:21:30 +01:00
|
|
|
|
|
|
|
|
|
object applyInt(object parameters, env currentEnv)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 2)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (!properList(CAR(CDR(parameters))) ||
|
|
|
|
|
TYPE(CAR(parameters)) != procedureObject)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
return apply(CAR(parameters), CAR(CDR(parameters)), currentEnv);
|
|
|
|
|
}
|
2019-02-13 12:09:35 +01:00
|
|
|
|
|
|
|
|
|
object displayInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TYPE(CAR(parameters)) == stringObject)
|
|
|
|
|
{
|
|
|
|
|
printf("%s", STR(CAR(parameters)));
|
|
|
|
|
}
|
|
|
|
|
else if (TYPE(CAR(parameters)) == charObject)
|
|
|
|
|
{
|
|
|
|
|
putwchar(CHR(CAR(parameters)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
return copyObject(CAR(parameters));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object printInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printValue(CAR(parameters));
|
|
|
|
|
return copyObject(CAR(parameters));
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-21 21:41:46 +01:00
|
|
|
|
object readInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 0)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Read("", stdin);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 12:09:35 +01:00
|
|
|
|
object beginInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
object last;
|
|
|
|
|
if (listLength(parameters) == 0)
|
|
|
|
|
{
|
|
|
|
|
TYPE(last) = nilObject;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
object *current = ¶meters;
|
|
|
|
|
while (TYPE(CDR(*current)) != nilObject)
|
|
|
|
|
{
|
|
|
|
|
current = &CDR(*current);
|
|
|
|
|
}
|
|
|
|
|
last = copyObject(CAR(*current));
|
|
|
|
|
}
|
|
|
|
|
return last;
|
|
|
|
|
}
|
2019-02-18 01:17:47 +01:00
|
|
|
|
|
2019-02-18 23:20:44 +01:00
|
|
|
|
object throwInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (TYPE(CAR(parameters)) != stringObject)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = errorObject;
|
|
|
|
|
ERR(result) = malloc((strlen(STR(CAR(parameters))) + 1) *
|
|
|
|
|
sizeof(char));
|
|
|
|
|
strcpy(ERR(result), STR(CAR(parameters)));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-18 01:17:47 +01:00
|
|
|
|
object makeStrInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) != 2)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (TYPE(CAR(parameters)) != numberObject || !integer(CAR(parameters))
|
|
|
|
|
|| TYPE(CAR(CDR(parameters))) != charObject)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
TYPE(result) = stringObject;
|
|
|
|
|
if (CHR(CAR(CDR(parameters))) == L'\0')
|
|
|
|
|
{
|
|
|
|
|
STR(result) = malloc(sizeof(char));
|
|
|
|
|
STR(result)[0] = '\0';
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
STR(result) = malloc((MB_CUR_MAX * NUM_NUMER(CAR(parameters)) + 1) *
|
|
|
|
|
sizeof(char));
|
|
|
|
|
if (STR(result) == NULL)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(outOfMemoryError);
|
|
|
|
|
}
|
|
|
|
|
int i, index;
|
|
|
|
|
for (i = 0, index = 0; i < NUM_NUMER(CAR(parameters)); ++i,
|
|
|
|
|
index += wctomb(STR(result) + index,
|
|
|
|
|
CHR(CAR(CDR(parameters)))))
|
|
|
|
|
;
|
|
|
|
|
STR(result)[index] = '\0';
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-28 23:43:33 +01:00
|
|
|
|
object charInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) != 2)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (TYPE(CAR(parameters)) != stringObject ||
|
|
|
|
|
TYPE(CAR(CDR(parameters))) != numberObject ||
|
|
|
|
|
!integer(CAR(CDR(parameters))))
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TYPE(result) = charObject;
|
|
|
|
|
char *mbs = STR(CAR(parameters));
|
|
|
|
|
int index = NUM_NUMER(CAR(CDR(parameters))), current = 0;
|
|
|
|
|
for (current = 0; current < index && *mbs != '\0';
|
|
|
|
|
mbs += mblen(mbs, MB_CUR_MAX), ++current)
|
|
|
|
|
;
|
|
|
|
|
mbtowc(&CHR(result), mbs, MB_CUR_MAX);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-18 01:17:47 +01:00
|
|
|
|
object strLengthInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
object result;
|
|
|
|
|
if (listLength(parameters) != 1)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(argumentNumberError);
|
|
|
|
|
}
|
|
|
|
|
if (TYPE(CAR(parameters)) != stringObject)
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
TYPE(result) = numberObject;
|
|
|
|
|
NUM_TYPE(result) = fractionNum;
|
|
|
|
|
NUM_DENOM(result) = 1;
|
|
|
|
|
|
|
|
|
|
wchar_t current;
|
|
|
|
|
int i = 0, length = 0;
|
|
|
|
|
int cLength;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
cLength =
|
|
|
|
|
mbtowc(¤t, &STR(CAR(parameters))[i], MB_CUR_MAX);
|
|
|
|
|
i += cLength;
|
|
|
|
|
++length;
|
|
|
|
|
} while (current != L'\0');
|
|
|
|
|
length -= 1; /* одузима се дужина нул карактера */
|
|
|
|
|
NUM_NUMER(result) = length;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2019-02-28 23:43:33 +01:00
|
|
|
|
|
|
|
|
|
object catInt(object parameters)
|
|
|
|
|
{
|
|
|
|
|
if (!allStrings(parameters))
|
|
|
|
|
{
|
|
|
|
|
SIGERR(typeError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object result;
|
|
|
|
|
TYPE(result) = stringObject;
|
|
|
|
|
int stringLength = 0;
|
|
|
|
|
object *current = ¶meters;
|
|
|
|
|
while (TYPE(*current) != nilObject)
|
|
|
|
|
{
|
|
|
|
|
stringLength += strlen(STR(CAR(*current)));
|
|
|
|
|
current = &CDR(*current);
|
|
|
|
|
}
|
|
|
|
|
STR(result) = malloc((stringLength + 1) * sizeof(char));
|
|
|
|
|
STR(result)[0] = '\0';
|
|
|
|
|
|
|
|
|
|
current = ¶meters;
|
|
|
|
|
while (TYPE(*current) != nilObject)
|
|
|
|
|
{
|
|
|
|
|
strcat(STR(result), STR(CAR(*current)));
|
|
|
|
|
current = &CDR(*current);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|