Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sanitizer and integrate github workflows #10

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: C/C++ CI

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
job_1:
name: ubuntu build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: make
run: |
make
cd sanitizer
make
- name: Upload the artifact
uses: actions/upload-artifact@v3
with:
name: purrgram_ubuntu
path: |
build/release/purr
build/sanitizer

job_2:
name: windows build
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: make
run: |
make
cd sanitizer
make
- name: Upload the artifact
uses: actions/upload-artifact@v3
with:
name: purrgram_windows
path: |
build/release/purr.exe
build/sanitizer.exe

job_3:
name: macOS build
runs-on: macOS-latest
steps:
- uses: actions/checkout@v3
- name: make
run: |
make
cd sanitizer
make
- name: Upload the artifact
uses: actions/upload-artifact@v3
with:
name: purrgram_macOS
path: |
build/release/purr
build/sanitizer

28 changes: 28 additions & 0 deletions sanitizer/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Define variables for directories and compiler options
SRC_DIR := ../src
BUILD_DIR := ../build
CC := gcc
CFLAGS := -Wall -Wextra -Ofast

# Define the target and dependencies
TARGET := $(BUILD_DIR)/sanitizer
SOURCES := main.c $(SRC_DIR)/scanner.c

# Define the default target
all: $(TARGET)

# Build the target executable
$(TARGET): $(SOURCES)
mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES)

# Define a rule to run the program with optional arguments
run: $(TARGET)
$(TARGET) $(ARGS)

# Define a rule to clean up the build directory
clean:
rm -f $(TARGET)

.PHONY: all run clean

190 changes: 190 additions & 0 deletions sanitizer/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../src/scanner.h"
#include "vector.h"

static char *readFile(const char *path)
{
FILE *file = fopen(path, "rb");
if (file == NULL)
{
fprintf(stderr, "Could not open file \"%s\".\n", path);
exit(74);
}

fseek(file, 0L, SEEK_END);
size_t fileSize = ftell(file);
rewind(file);

char *buffer = (char *)malloc(fileSize + 1);
if (buffer == NULL)
{
fprintf(stderr, "Not enough memory to read \"%s\".\n", path);
exit(74);
}

size_t bytesRead = fread(buffer, sizeof(char), fileSize, file);
if (bytesRead < fileSize)
{
fprintf(stderr, "Could not read file \"%s\".\n", path);
exit(74);
}

buffer[bytesRead] = '\0';

fclose(file);
return buffer;
}

DEFINE_VECTOR(int)

void addsemicolon(const char *source)
{
vector_int pos;
vector_init_int(&pos);

initScanner(source);

Token prevToken, curToken;

curToken = scanToken();

int semicolonCount = 0;

while (curToken.type != TOKEN_EOF)
{
prevToken = curToken;
const char *curPos = curToken.start + curToken.length;
curToken = scanToken();

if (prevToken.line != curToken.line)
{
switch (prevToken.type)
{
case TOKEN_RIGHT_PAREN:
case TOKEN_RIGHT_BRACKET:
case TOKEN_IDENTIFIER:
case TOKEN_STRING:
case TOKEN_NUMBER:
case TOKEN_FALSE:
case TOKEN_NONE:
case TOKEN_TRUE: {
switch (curToken.type)
{
case TOKEN_LEFT_PAREN:
case TOKEN_LEFT_BRACKET:
case TOKEN_IDENTIFIER:
case TOKEN_STRING:
case TOKEN_NUMBER:
case TOKEN_BREAK:
case TOKEN_CONTINUE:
case TOKEN_DEF:
case TOKEN_ELIF:
case TOKEN_ELSE:
case TOKEN_END:
case TOKEN_FALSE:
case TOKEN_FOR:
case TOKEN_IF:
case TOKEN_NONE:
case TOKEN_RETURN:
case TOKEN_TRUE:
case TOKEN_VAR:
case TOKEN_WHILE:
semicolonCount++;
vector_push_back_int(&pos, curPos - source);
break;
}
break;
}
case TOKEN_BREAK:
case TOKEN_CONTINUE:
semicolonCount++;
vector_push_back_int(&pos, curPos - source);
break;
case TOKEN_RETURN: {
switch (curToken.type)
{
case TOKEN_BREAK:
case TOKEN_CONTINUE:
case TOKEN_DEF:
case TOKEN_ELIF:
case TOKEN_ELSE:
case TOKEN_END:
case TOKEN_FOR:
case TOKEN_IF:
case TOKEN_RETURN:
case TOKEN_VAR:
case TOKEN_WHILE:
semicolonCount++;
vector_push_back_int(&pos, curPos - source);
break;
}
break;
}
}
}
}

switch (prevToken.type)
{
case TOKEN_RIGHT_PAREN:
case TOKEN_RIGHT_BRACKET:
case TOKEN_IDENTIFIER:
case TOKEN_STRING:
case TOKEN_NUMBER:
case TOKEN_BREAK:
case TOKEN_CONTINUE:
case TOKEN_FALSE:
case TOKEN_NONE:
case TOKEN_RETURN:
case TOKEN_TRUE:
semicolonCount++;
vector_push_back_int(&pos, prevToken.start + prevToken.length - source);
break;
}

int srcLen = strlen(source);
int len = srcLen + semicolonCount;
char *rectified = (char *)malloc(sizeof(char) * (len + 1));

int j = 0;

for (int i = 0, k = 0; i < srcLen;)
{
if (i == pos.elements[k])
{
rectified[j++] = ';';
k++;
}
else
{
rectified[j++] = source[i++];
}
}

rectified[j] = '\0';

printf("%s", rectified);

free(rectified);
vector_free_int(&pos);
}

int main(int argc, const char *argv[])
{
if (argc == 2)
{
char *source = readFile(argv[1]);
addsemicolon(source);
free(source);
}
else
{
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
exit(1);
}

return 0;
}
Loading