Selaa lähdekoodia

functions signature consists of their name and number of arguments,
argument amountt of functions and function calls must match

Kajetan Johannes Hammerle 3 vuotta sitten
vanhempi
commit
badf6ab7e9
6 muutettua tiedostoa jossa 92 lisäystä ja 12 poistoa
  1. 11 11
      Compiler.c
  2. 38 0
      FunctionMap.c
  3. 23 0
      FunctionMap.h
  4. 2 1
      meson.build
  5. 13 0
      tests/functions/overloading
  6. 5 0
      tests/functions/overloading.out

+ 11 - 11
Compiler.c

@@ -2,6 +2,7 @@
 #include <stdio.h>
 
 #include "Compiler.h"
+#include "FunctionMap.h"
 #include "Operation.h"
 #include "StringIntMap.h"
 #include "Tokenizer.h"
@@ -18,7 +19,7 @@ static int16 line = 1;
 
 static int varIndex = 0;
 static StringIntMap vars[2];
-static StringIntMap functions;
+static FunctionMap functions;
 
 static void cError(const char* format, ...) {
     va_list args;
@@ -172,11 +173,6 @@ static bool cSetVar(const char* literal) {
 }
 
 static bool cCallFunction(const char* literal) {
-    int index;
-    if(!simSearch(&functions, literal, &index)) {
-        cError("unknown function on line %d", line);
-        return false;
-    }
     int arguments = 0;
     while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
         arguments++;
@@ -187,8 +183,13 @@ static bool cCallFunction(const char* literal) {
             return false;
         }
     }
+    int address = fmSearchAddress(&functions, literal, arguments);
+    if(address == -1) {
+        cError("unknown function on line %d", line);
+        return false;
+    }
     cAddOperation(OP_GOSUB);
-    cAddInt(index);
+    cAddInt(address);
     cAddInt(arguments);
     return cConsumeToken(T_SEMICOLON);
 }
@@ -255,8 +256,7 @@ static bool cFunction() {
     cAddOperation(OP_GOTO);
     int gotoIndex = cReserveInt();
 
-    int functionIndex = code->length;
-    if(!simAdd(&functions, name, &functionIndex)) {
+    if(!fmAdd(&functions, name, arguments, code->length)) {
         cError("function registered twice on line %d", line);
         return false;
     }
@@ -325,9 +325,9 @@ static void cAllocAndCompile() {
     varIndex = 0;
     simInit(vars);
     simInit(vars + 1);
-    simInit(&functions);
+    fmInit(&functions);
     cForEachLine();
-    simDelete(&functions);
+    fmDelete(&functions);
     simDelete(vars + 1);
     simDelete(vars);
 }

+ 38 - 0
FunctionMap.c

@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "FunctionMap.h"
+
+void fmInit(FunctionMap* fm) {
+    fm->capacity = 16;
+    fm->entries = 0;
+    fm->data = malloc(sizeof(Function) * fm->capacity);
+}
+
+void fmDelete(FunctionMap* fm) {
+    free(fm->data);
+}
+
+int fmSearchAddress(FunctionMap* fm, const char* name, int arguments) {
+    for(int i = 0; i < fm->entries; i++) {
+        if(fm->data[i].arguments == arguments && strcmp(fm->data[i].name, name) == 0) {
+            return fm->data[i].address;
+        }
+    }
+    return -1;
+}
+
+bool fmAdd(FunctionMap* fm, const char* name, int arguments, int address) {
+    if(fmSearchAddress(fm, name, arguments) != -1) {
+        return false;
+    }
+    if(fm->entries >= fm->capacity) {
+        fm->capacity *= 2;
+        fm->data = realloc(fm->data, sizeof(Function) * fm->capacity);
+    }
+    int index = fm->entries++;
+    fm->data[index].name = name;
+    fm->data[index].arguments = arguments;
+    fm->data[index].address = address;
+    return true;
+}

+ 23 - 0
FunctionMap.h

@@ -0,0 +1,23 @@
+#ifndef FUNCTIONMAP_H
+#define FUNCTIONMAP_H
+
+#include <stdbool.h>
+
+typedef struct Function {
+    const char* name;
+    int arguments;
+    int address;
+} Function;
+
+typedef struct FunctionMap {
+    int capacity;
+    int entries;
+    Function* data;
+} FunctionMap;
+
+void fmInit(FunctionMap* fm);
+void fmDelete(FunctionMap* fm);
+int fmSearchAddress(FunctionMap* fm, const char* name, int arguments);
+bool fmAdd(FunctionMap* fm, const char* name, int arguments, int address);
+
+#endif

+ 2 - 1
meson.build

@@ -8,7 +8,8 @@ src = [
     'Script.c', 
     'Test.c', 
     'StringIntMap.c',
-    'ByteCode.c'
+    'ByteCode.c',
+    'FunctionMap.c'
 ]
 
 executable('lonely_tiger', 

+ 13 - 0
tests/functions/overloading

@@ -0,0 +1,13 @@
+function test(a, b) {
+    print a + 1;
+    print b + 2;
+}
+
+function test(a, b, c) {
+    print a + 3;
+    print b + 4;
+    print c + 100;
+}
+
+test(1, 2);
+test(10, 20, 1);

+ 5 - 0
tests/functions/overloading.out

@@ -0,0 +1,5 @@
+2
+4
+13
+24
+101