cirilisp/cirilisp.c

178 lines
5.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <locale.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "internals.h"
#include "read.h"
#include "eval.h"
#include "print.h"
extern env globalEnv;
extern int eofStatus;
int load(char *pathname)
{
FILE *stream;
if ((stream = fopen(pathname, "r")) == NULL)
{
return 0;
}
object exp;
while (TYPE(exp = Eval(Read("", stream), globalEnv)) != EOFObject)
{
if (TYPE(exp) == errorObject)
{
Print(exp);
}
else
{
deleteObject(exp);
}
}
eofStatus = 0;
fclose(stream);
return 1;
}
void exitCirilisp(int exitStatus)
/* терминира програм са жељеним излазним статусом, притом брише глобално
* окружење које једино и може бити активно током изласка из програма, и
* брише још неке динамички алоциране предмете у меморији */
{
if (globalEnv != NULL)
{
removeEnvironment(globalEnv);
}
extern wchar_t *globalBuffer;
if (globalBuffer != NULL)
{
free(globalBuffer);
}
exit(exitStatus);
}
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");
exitCirilisp(0);
}
/* Омогућава библиотекама коришћеним у интерпретеру да протумаче српску
* ћирилицу */
globalEnv = createEnvironment(NULL);
addSymbolInternal("листа?", &listQInt, 0);
addSymbolInternal("број?", &numberQInt, 0);
addSymbolInternal("<", &lessInt, 0);
addSymbolInternal("/", &divideInt, 0);
addSymbolInternal("+", &addInt, 0);
addSymbolInternal("=", &eqNumInt, 0);
addSymbolInternal(">", &greaterInt, 0);
addSymbolInternal("-", &subtractInt, 0);
addSymbolInternal("*", &multiplyInt, 0);
addSymbolInternal("ако", &ifInt, 1);
addSymbolInternal("баци", &throwInt, 0);
addSymbolInternal("јед?", &eqvQInt, 0);
addSymbolInternal("булски?", &boolQInt, 0);
addSymbolInternal("бројилац", &numeratorInt, 0);
addSymbolInternal("дужина-ниске", &strLengthInt, 0);
addSymbolInternal("именилац", &denominatorInt, 0);
addSymbolInternal("конс", &consInt, 0);
addSymbolInternal("карактер", &charInt, 0);
addSymbolInternal("карактер?", &charQInt, 0);
addSymbolInternal("конс?", &consQInt, 0);
addSymbolInternal("људи", &lambdaInt, 1);
addSymbolInternal("прикажи", &displayInt, 0);
addSymbolInternal("нил?", &nilQInt, 0);
addSymbolInternal("направи-ниску", &makeStrInt, 0);
addSymbolInternal("надовежи", &appendInt, 0);
addSymbolInternal("навод", &quoteInt, 1);
addSymbolInternal("нетачно->тачно", &inexactToExactInt, 0);
addSymbolInternal("опиши", &defineInt, 1);
addSymbolInternal("опиши-складњу", &defineMacroInt, 1);
addSymbolInternal("почни", &beginInt, 1);
addSymbolInternal("ниска?", &stringQInt, 0);
addSymbolInternal("сар", &carInt, 0);
addSymbolInternal("разломак?", &fractionQInt, 0);
addSymbolInternal("процедура?", &procedureQInt, 0);
addSymbolInternal("примени", &applyInt, 0);
addSymbolInternal("реалан?", &realQInt, 0);
addSymbolInternal("тачно->нетачно", &exactToInexactInt, 0);
addSymbolInternal("сдр", &cdrInt, 0);
addSymbolInternal("свежи-ниске", &catInt, 0);
addSymbolInternal("симбол?", &symbolQInt, 0);
addSymbolInternal("читај", &readInt, 0);
addSymbolInternal("штампај", &printInt, 0);
if (!load(DESTDIR "/usr/local/lib/cirilisp/инит.ћ"))
{
fprintf(stderr, "Није пронађена стандардна ЋИРЛИСП библиотека\
\nПрограм се није могао правилно покренути\n");
exitCirilisp(3);
}
}
const char *help =
"\
Команда: cirilisp [-q|-v|-h] [<име фајла>]*\n\
Опције:\n\
-q Не започињи ЧПШП (\"Читај, процени, штампај\" петљу) након\
евалуирања командних аргумената\n\
-h Одштампај овај кратки помоћник и затвори програм\n\
-v Одштампај верзију програма и затвори програм\n\
";
int main(int argc, char **argv)
{
init();
int quitFlag = 0, opt;
while ((opt = getopt(argc, argv, "qvh")) != -1)
{
switch (opt)
{
case 'q':
quitFlag = 1;
break;
case 'v':
printf("Верзија: " VERSION "\n");
exitCirilisp(0);
break;
case 'h':
printf(help);
exitCirilisp(0);
break;
default:
fprintf(stderr, "Непозната командна опција");
exitCirilisp(1);
}
}
while (argv[optind] != NULL)
{
if (!load(argv[optind]))
{
fprintf(stderr, "Није било могуће отворити фајл %s.\n\
Проверите да ли дати фајл заиста постоји\n", argv[optind]);
exitCirilisp(2);
}
++optind;
}
if (quitFlag)
{
exitCirilisp(0);
}
printf("Добродошли у ЋИРИЛИСП ЧПШП окружење, верзија: " VERSION "\n");
object current;
while (Print(current = Eval(Read("Ћ> ", stdin), globalEnv)))
deleteObject(current);
printf("\nДостигнут крај улазног тока.\nЗбогом и дођите нам опет!\n");
exitCirilisp(0);
}