summaryrefslogtreecommitdiff
path: root/src/main.c
blob: a5721d3333e91499b40bd9f7c2c35eb76f03280a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "runner/runner.h"
#include "utils/file.h"
#include "utils/log.h"
#include <stdio.h>
#include <time.h>

// #define PRINT_COMPILE_TREE
#define PRINT_STATISTICS

#ifdef PRINT_STATISTICS
static struct timespec diff(struct timespec end, struct timespec start) {
  struct timespec temp;
  if ((end.tv_nsec - start.tv_nsec) < 0) {
    temp.tv_sec = end.tv_sec - start.tv_sec - 1;
    temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
  } else {
    temp.tv_sec = end.tv_sec - start.tv_sec;
    temp.tv_nsec = end.tv_nsec - start.tv_nsec;
  }
  return temp;
}

static struct timespec add(struct timespec left, struct timespec right) {
  struct timespec result;
  result.tv_nsec = left.tv_nsec + right.tv_nsec;
  result.tv_sec = (left.tv_sec + right.tv_sec) + result.tv_nsec / 1000000000;
  result.tv_nsec %= 1000000000;
  return result;
}

static void printTime(struct timespec time) {
  printf("%02ld:%02ld.%09ldns", time.tv_sec / 60, time.tv_sec % 60,
         time.tv_nsec);
}
#endif

static int runWithoutRead(char *code) {
#ifdef PRINT_STATISTICS
  struct timespec start, end;
  struct timespec lexTime;
  struct timespec parseTime;
  struct timespec astTime;
  struct timespec runTime;
  struct timespec totalTime = {0};
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
#endif
  LexerNodeArray lexed = lexer(code);
  if (lexerNodeArrayIsError(lexed)) {
    return 1;
  }
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
  lexTime = diff(end, start);
  totalTime = add(totalTime, lexTime);
#endif
#ifdef PRINT_COMPILE_TREE
  lexerNodeArrayPrint(lexed);
#endif
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
#endif

  ParserNode *parsedRoot = parser(lexed);
  lexerNodeArrayDestroy(lexed);
  if (parsedRoot == NULL) {
    return 1;
  }
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
  parseTime = diff(end, start);
  totalTime = add(totalTime, parseTime);
#endif
#ifdef PRINT_COMPILE_TREE
  parserNodePrint(parsedRoot, 0);
#endif
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
#endif

  AstTreeRoot *astTree = makeAstTree(parsedRoot);
  parserNodeDelete(parsedRoot);
  if (astTree == NULL) {
    return 1;
  }
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
  astTime = diff(end, start);
  totalTime = add(totalTime, astTime);
#endif
#ifdef PRINT_COMPILE_TREE
  astTreeRootPrint(astTree);
#endif
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
#endif

  int ret;
  if (runAstTree(astTree)) {
    ret = 0;
  } else {
    ret = 1;
  }
  astTreeRootDelete(astTree);
#ifdef PRINT_STATISTICS
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
  runTime = diff(end, start);
  totalTime = add(totalTime, runTime);
#endif

#ifdef PRINT_STATISTICS
  printf("----\nlexTime:   ");
  printTime(lexTime);
  printf("\nparseTime: ");
  printTime(parseTime);
  printf("\nastTime:   ");
  printTime(astTime);
  printf("\nrunTime:   ");
  printTime(runTime);
  printf("\ntotal:     ");
  printTime(totalTime);
  printf("\n");
#endif

  return ret;
}

static int run(const char *filePath) {
  char *code = readWholeFile(filePath);

  if (code == NULL) {
    return 1;
  }

  return runWithoutRead(code);
}

int main(int argc, char *argv[]) {
  fileInit();

  if (argc < 2) {
    // compileRun("test/main.felan", "build/out", false);
    // run("test/main.felan", false);
    printLog("Too few args");
    return 1;
  }

  const int ret = run(argv[1]);
  fileDelete();
  return ret;
}