Додате основне функције за конструкцију ниски

This commit is contained in:
kappa 2019-02-18 01:17:47 +01:00
parent 816a67a770
commit 0577bf8663
6 changed files with 140 additions and 1 deletions

View file

@ -58,6 +58,7 @@ void init()
addSymbolInternal("ниска?", &stringQInt, 0); addSymbolInternal("ниска?", &stringQInt, 0);
addSymbolInternal("карактер?", &charQInt, 0); addSymbolInternal("карактер?", &charQInt, 0);
addSymbolInternal("листа?", &listQInt, 0); addSymbolInternal("листа?", &listQInt, 0);
addSymbolInternal("надовежи", &appendInt, 0);
addSymbolInternal("конс", &consInt, 0); addSymbolInternal("конс", &consInt, 0);
addSymbolInternal("сар", &carInt, 0); addSymbolInternal("сар", &carInt, 0);
addSymbolInternal("сдр", &cdrInt, 0); addSymbolInternal("сдр", &cdrInt, 0);
@ -66,6 +67,8 @@ void init()
addSymbolInternal("прикажи", &displayInt, 0); addSymbolInternal("прикажи", &displayInt, 0);
addSymbolInternal("штампај", &printInt, 0); addSymbolInternal("штампај", &printInt, 0);
addSymbolInternal("почни", &beginInt, 0); addSymbolInternal("почни", &beginInt, 0);
addSymbolInternal("направи-ниску", &makeStrInt, 0);
addSymbolInternal("дужина-ниске", &strLengthInt, 0);
if (!load(DESTDIR"/usr/local/lib/cirilisp/инит.ћ")) if (!load(DESTDIR"/usr/local/lib/cirilisp/инит.ћ"))
{ {

View file

@ -1,10 +1,12 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h>
#include "util.h" #include "util.h"
#include "print.h" #include "read.h"
#include "eval.h" #include "eval.h"
#include "print.h"
int allNums(object list) int allNums(object list)
/* проверава да ли је објекат листа чији је сваки члан број, претпоставља да је /* проверава да ли је објекат листа чији је сваки члан број, претпоставља да је
@ -533,6 +535,57 @@ object listQInt(object parameters)
return result; return result;
} }
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);
}
object consInt(object parameters) object consInt(object parameters)
{ {
if (listLength(parameters) != 2) if (listLength(parameters) != 2)
@ -704,3 +757,69 @@ object beginInt(object parameters)
} }
return last; return last;
} }
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;
}
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(&current, &STR(CAR(parameters))[i], MB_CUR_MAX);
i += cLength;
++length;
} while (current != L'\0');
length -= 1; /* одузима се дужина нул карактера */
NUM_NUMER(result) = length;
return result;
}

View file

@ -24,6 +24,7 @@ object boolQInt(object parameters);
object stringQInt(object parameters); object stringQInt(object parameters);
object charQInt(object parameters); object charQInt(object parameters);
object listQInt(object parameters); object listQInt(object parameters);
object appendInt(object parameters);
object consInt(object parameters); object consInt(object parameters);
object carInt(object parameters); object carInt(object parameters);
object cdrInt(object parameters); object cdrInt(object parameters);
@ -32,3 +33,5 @@ object applyInt(object parameters, env currentEnv);
object displayInt(object parameters); object displayInt(object parameters);
object printInt(object parameters); object printInt(object parameters);
object beginInt(object parameters); object beginInt(object parameters);
object makeStrInt(object parameters);
object strLengthInt(object parameters);

View file

@ -16,6 +16,7 @@ char *errors[] =
"Невалидна тараба-секвенца", "Невалидна тараба-секвенца",
"Неочекивани крај фајла", "Неочекивани крај фајла",
"Неочекивана заграда", "Неочекивана заграда",
"Недовољно меморије доступно"
}; };
void printValue(object input); void printValue(object input);

9
util.c
View file

@ -491,6 +491,15 @@ int cmp(object a, object b)
} }
} }
int integer(object a)
{
if (NUM_TYPE(a) != fractionNum || NUM_DENOM(a) != 1)
{
return 0;
}
return 1;
}
object intToBool(int boolean) object intToBool(int boolean)
{ {
object result; object result;

4
util.h
View file

@ -64,6 +64,7 @@ typedef enum
invalidHashSequenceError, invalidHashSequenceError,
unexpectedEOFError, unexpectedEOFError,
unmatchedParenError, unmatchedParenError,
outOfMemoryError
} error; } error;
typedef enum typedef enum
@ -197,6 +198,9 @@ object inverseNum(object a);
int cmp(object a, object b); int cmp(object a, object b);
/* пореди два броја и враћа -1, 0, 1 у зависности од односа истих, претпоставља /* пореди два броја и враћа -1, 0, 1 у зависности од односа истих, претпоставља
* да су објекти бројеви */ * да су објекти бројеви */
int integer(object a);
/* проверава да ли је дати број разломачки и такође цео, претпоставља да је
* дати објекат број */
object intToBool(int boolean); object intToBool(int boolean);