2019-02-09 23:54:56 +01:00
|
|
|
|
#include <locale.h>
|
2019-02-19 09:49:55 +01:00
|
|
|
|
#include <unistd.h>
|
2019-02-09 19:55:51 +01:00
|
|
|
|
#include <stdio.h>
|
2019-02-09 23:54:56 +01:00
|
|
|
|
#include <stdlib.h>
|
2019-02-09 19:55:51 +01:00
|
|
|
|
|
2019-02-09 23:54:56 +01:00
|
|
|
|
#include "internals.h"
|
2019-01-08 22:19:29 +01:00
|
|
|
|
#include "read.h"
|
2019-01-14 03:16:25 +01:00
|
|
|
|
#include "eval.h"
|
2019-01-08 22:19:29 +01:00
|
|
|
|
#include "print.h"
|
2019-01-03 16:59:28 +01:00
|
|
|
|
|
2019-03-23 14:10:16 +01:00
|
|
|
|
extern env globalEnv;
|
|
|
|
|
|
2019-02-09 23:54:56 +01:00
|
|
|
|
extern int eofStatus;
|
|
|
|
|
int load(char *pathname)
|
|
|
|
|
{
|
|
|
|
|
FILE *stream;
|
|
|
|
|
if ((stream = fopen(pathname, "r")) == NULL)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-02-10 22:21:20 +01:00
|
|
|
|
object exp;
|
2019-02-19 09:49:55 +01:00
|
|
|
|
while (TYPE(exp = Eval(Read("", stream), globalEnv)) != EOFObject)
|
2019-02-18 23:20:44 +01:00
|
|
|
|
{
|
|
|
|
|
if (TYPE(exp) == errorObject)
|
|
|
|
|
{
|
2019-02-19 09:49:55 +01:00
|
|
|
|
Print(exp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
deleteObject(exp);
|
2019-02-18 23:20:44 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-09 23:54:56 +01:00
|
|
|
|
eofStatus = 0;
|
|
|
|
|
fclose(stream);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-23 14:10:16 +01:00
|
|
|
|
void exitCirilisp(int exitStatus)
|
|
|
|
|
/* терминира програм са жељеним излазним статусом, притом брише глобално
|
|
|
|
|
* окружење које једино и може бити активно током изласка из програма, и
|
|
|
|
|
* брише још неке динамички алоциране предмете у меморији */
|
|
|
|
|
{
|
|
|
|
|
if (globalEnv != NULL)
|
|
|
|
|
{
|
|
|
|
|
removeEnvironment(globalEnv);
|
|
|
|
|
}
|
|
|
|
|
extern wchar_t *globalBuffer;
|
|
|
|
|
if (globalBuffer != NULL)
|
|
|
|
|
{
|
|
|
|
|
free(globalBuffer);
|
|
|
|
|
}
|
|
|
|
|
exit(exitStatus);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-09 23:54:56 +01:00
|
|
|
|
void init()
|
|
|
|
|
{
|
|
|
|
|
if (setlocale(LC_ALL, "sr_RS.utf8") == NULL)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "lokal programa se nije mogao podesiti na\
|
|
|
|
|
\"sr_RS.utf8\", proverite da li ste ga osposobili na vasem sistemu\n");
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(0);
|
2019-02-09 23:54:56 +01:00
|
|
|
|
}
|
|
|
|
|
/* Омогућава библиотекама коришћеним у интерпретеру да протумаче српску
|
|
|
|
|
* ћирилицу */
|
|
|
|
|
|
|
|
|
|
globalEnv = createEnvironment(NULL);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("листа?", &listQInt, 0);
|
|
|
|
|
addSymbolInternal("број?", &numberQInt, 0);
|
|
|
|
|
addSymbolInternal("<", &lessInt, 0);
|
|
|
|
|
addSymbolInternal("/", ÷Int, 0);
|
2019-02-09 23:54:56 +01:00
|
|
|
|
addSymbolInternal("+", &addInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("=", &eqNumInt, 0);
|
|
|
|
|
addSymbolInternal(">", &greaterInt, 0);
|
2019-02-09 23:54:56 +01:00
|
|
|
|
addSymbolInternal("-", &subtractInt, 0);
|
|
|
|
|
addSymbolInternal("*", &multiplyInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("ако", &ifInt, 1);
|
|
|
|
|
addSymbolInternal("баци", &throwInt, 0);
|
|
|
|
|
addSymbolInternal("јед?", &eqvQInt, 0);
|
|
|
|
|
addSymbolInternal("булски?", &boolQInt, 0);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
addSymbolInternal("бројилац", &numeratorInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("дужина-ниске", &strLengthInt, 0);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
addSymbolInternal("именилац", &denominatorInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("конс", &consInt, 0);
|
2019-02-28 23:43:33 +01:00
|
|
|
|
addSymbolInternal("карактер", &charInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("карактер?", &charQInt, 0);
|
|
|
|
|
addSymbolInternal("конс?", &consQInt, 0);
|
2019-09-19 20:37:22 +02:00
|
|
|
|
addSymbolInternal("људи", &lambdaInt, 1);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("прикажи", &displayInt, 0);
|
|
|
|
|
addSymbolInternal("нил?", &nilQInt, 0);
|
|
|
|
|
addSymbolInternal("направи-ниску", &makeStrInt, 0);
|
|
|
|
|
addSymbolInternal("надовежи", &appendInt, 0);
|
2019-02-09 23:54:56 +01:00
|
|
|
|
addSymbolInternal("навод", "eInt, 1);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0);
|
2019-02-13 12:09:35 +01:00
|
|
|
|
addSymbolInternal("опиши", &defineInt, 1);
|
|
|
|
|
addSymbolInternal("опиши-складњу", &defineMacroInt, 1);
|
2019-09-21 10:53:37 +02:00
|
|
|
|
addSymbolInternal("почни", &beginInt, 1);
|
2019-02-10 22:21:20 +01:00
|
|
|
|
addSymbolInternal("ниска?", &stringQInt, 0);
|
2019-02-11 11:21:30 +01:00
|
|
|
|
addSymbolInternal("сар", &carInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("разломак?", &fractionQInt, 0);
|
|
|
|
|
addSymbolInternal("процедура?", &procedureQInt, 0);
|
2019-02-11 11:21:30 +01:00
|
|
|
|
addSymbolInternal("примени", &applyInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("реалан?", &realQInt, 0);
|
|
|
|
|
addSymbolInternal("тачно->нетачно", &exactToInexactInt, 0);
|
|
|
|
|
addSymbolInternal("сдр", &cdrInt, 0);
|
2019-02-28 23:43:33 +01:00
|
|
|
|
addSymbolInternal("свежи-ниске", &catInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("симбол?", &symbolQInt, 0);
|
2019-02-21 21:41:46 +01:00
|
|
|
|
addSymbolInternal("читај", &readInt, 0);
|
2019-02-28 19:39:44 +01:00
|
|
|
|
addSymbolInternal("штампај", &printInt, 0);
|
2019-02-09 23:54:56 +01:00
|
|
|
|
|
2019-02-19 09:49:55 +01:00
|
|
|
|
if (!load(DESTDIR "/usr/local/lib/cirilisp/инит.ћ"))
|
2019-02-09 23:54:56 +01:00
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Није пронађена стандардна ЋИРЛИСП библиотека\
|
|
|
|
|
\nПрограм се није могао правилно покренути\n");
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(3);
|
2019-02-09 23:54:56 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-19 09:49:55 +01:00
|
|
|
|
const char *help =
|
|
|
|
|
"\
|
|
|
|
|
Команда: cirilisp [-q|-v|-h] [<име фајла>]*\n\
|
|
|
|
|
Опције:\n\
|
2019-02-19 17:10:25 +01:00
|
|
|
|
-q Не започињи ЧПШП (\"Читај, процени, штампај\" петљу) након\
|
|
|
|
|
евалуирања командних аргумената\n\
|
2019-02-19 09:49:55 +01:00
|
|
|
|
-h Одштампај овај кратки помоћник и затвори програм\n\
|
|
|
|
|
-v Одштампај верзију програма и затвори програм\n\
|
|
|
|
|
";
|
|
|
|
|
|
2019-01-03 16:59:28 +01:00
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
|
{
|
2019-01-19 14:42:56 +01:00
|
|
|
|
init();
|
2019-02-19 09:49:55 +01:00
|
|
|
|
|
|
|
|
|
int quitFlag = 0, opt;
|
|
|
|
|
while ((opt = getopt(argc, argv, "qvh")) != -1)
|
|
|
|
|
{
|
|
|
|
|
switch (opt)
|
|
|
|
|
{
|
|
|
|
|
case 'q':
|
|
|
|
|
quitFlag = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'v':
|
|
|
|
|
printf("Верзија: " VERSION "\n");
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(0);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'h':
|
|
|
|
|
printf(help);
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(0);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(stderr, "Непозната командна опција");
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(1);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (argv[optind] != NULL)
|
|
|
|
|
{
|
|
|
|
|
if (!load(argv[optind]))
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Није било могуће отворити фајл %s.\n\
|
|
|
|
|
Проверите да ли дати фајл заиста постоји\n", argv[optind]);
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(2);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
}
|
|
|
|
|
++optind;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (quitFlag)
|
|
|
|
|
{
|
2019-03-23 14:10:16 +01:00
|
|
|
|
exitCirilisp(0);
|
2019-02-19 09:49:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("Добродошли у ЋИРИЛИСП ЧПШП окружење, верзија: " VERSION "\n");
|
2019-02-28 23:43:33 +01:00
|
|
|
|
while (Print(Eval(Read("Ћ> ", stdin), globalEnv)))
|
2019-02-10 22:21:20 +01:00
|
|
|
|
;
|
2019-02-09 23:54:56 +01:00
|
|
|
|
printf("\nДостигнут крај улазног тока.\nЗбогом и дођите нам опет!\n");
|
2019-02-09 19:55:51 +01:00
|
|
|
|
|
2019-03-23 22:07:31 +01:00
|
|
|
|
exitCirilisp(0);
|
2019-01-03 16:59:28 +01:00
|
|
|
|
}
|