Browse Source

basic foundation laid down

master
mort 7 years ago
commit
4d4d43aa31
6 changed files with 244 additions and 0 deletions
  1. 1
    0
      .gitignore
  2. 2
    0
      Makefile
  3. 141
    0
      src/lexer.c
  4. 37
    0
      src/lexer.h
  5. 7
    0
      src/main.c
  6. 56
    0
      src/vm.h

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
vm

+ 2
- 0
Makefile View File

@@ -0,0 +1,2 @@
build:
gcc -o vm src/*.c

+ 141
- 0
src/lexer.c View File

@@ -0,0 +1,141 @@
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>

#include "lexer.h"

static regex_t regex(const char* str)
{
regex_t reg;
int err = regcomp(&reg, str, REG_EXTENDED);
if (err)
{
fprintf(stderr, "Invalid regex: '%s'\n", str);
fprintf(stderr, "Error code: %i\n", err);
exit(1);
}

return reg;
}

static int regmatch(regex_t reg, char* str, regmatch_t* pmatch)
{
return (regexec(&reg, str, 1, pmatch, 0) != REG_NOMATCH);
}

static int tokens_append(
lexer_tokens* tokens,
lexer_token_class tokenClass,
char* str,
size_t len)
{
tokens->length += 1;
if (tokens->length > tokens->allocd)
{
tokens->allocd *= 2;
tokens->pairs = realloc(tokens->pairs, tokens->allocd);
if (!tokens->pairs)
return 1;
}

lexer_token pair = tokens->pairs[tokens->length - 1];
pair.tokenClass = tokenClass;
pair.str = str;
pair.len = len;

return 0;
}

lexer_tokens* lexer_analyze(char* str)
{
regex_t whitespace = regex("\\s+");
regex_t identifier = regex("[a-zA-Z][a-zA-Z0-9]*");
regex_t keyword = regex("if|ret|func|str|arr|err|null");
regex_t operator = regex("=|==");
regex_t separator = regex("\\,");

regex_t integer = regex("[0-9]+");
regex_t string = regex("\\\"[^\\\"]*\\\"");

regex_t function_start = regex("\\{");
regex_t function_end = regex("\\}");
regex_t expression_start = regex("\\(");
regex_t expression_end = regex("\\)");

lexer_tokens* tokens = malloc(sizeof(lexer_tokens));
if (!tokens)
return NULL;

tokens->pairs = NULL;
tokens->length = 0;
tokens->allocd = 0;

regmatch_t pmatch;
size_t offset = 0;

#define APPEND(tclass) tokens_append(tokens, tclass, str + offset + pmatch.rm_so, pmatch.rm_eo - pmatch.rm_so)

while (1)
{
if (regmatch(whitespace, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_WHITESPACE))
return NULL;
}
else if (regmatch(identifier, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_IDENTIFIER))
return NULL;
}
else if (regmatch(keyword, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_KEYWORD))
return NULL;
} else if (regmatch(operator, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_OPERATOR))
return NULL;
}
else if (regmatch(separator, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_SEPARATOR))
return NULL;
}
else if (regmatch(integer, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_INTEGER))
return NULL;
}
else if (regmatch(string, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_STRING))
return NULL;
}
else if (regmatch(function_start, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_FUNCTION_START))
return NULL;
}
else if (regmatch(function_end, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_FUNCTION_END))
return NULL;
}
else if (regmatch(expression_start, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_EXPRESSION_START))
return NULL;
}
else if (regmatch(expression_end, str + offset, &pmatch))
{
if (APPEND(LEXER_TOKEN_EXPRESSION_END))
return NULL;
}
else
{
return tokens;
}

offset += pmatch.rm_eo;
}
}

+ 37
- 0
src/lexer.h View File

@@ -0,0 +1,37 @@
#ifndef LEXER_H
#define LEXER_H

typedef enum lexer_token_class
{
LEXER_TOKEN_WHITESPACE,
LEXER_TOKEN_IDENTIFIER,
LEXER_TOKEN_KEYWORD,
LEXER_TOKEN_OPERATOR,
LEXER_TOKEN_SEPARATOR,

LEXER_TOKEN_INTEGER,
LEXER_TOKEN_STRING,

LEXER_TOKEN_FUNCTION_START,
LEXER_TOKEN_FUNCTION_END,
LEXER_TOKEN_EXPRESSION_START,
LEXER_TOKEN_EXPRESSION_END
} lexer_token_class;

typedef struct lexer_token
{
lexer_token_class tokenClass;
char* str;
size_t len;
} lexer_token;

typedef struct lexer_tokens
{
lexer_token* pairs;
size_t length;
size_t allocd;
} lexer_tokens;

lexer_tokens* lexer_analyze(char* str);

#endif

+ 7
- 0
src/main.c View File

@@ -0,0 +1,7 @@
#include <stdio.h>

#include "vm.h"

int main(int argc, char** argv)
{
}

+ 56
- 0
src/vm.h View File

@@ -0,0 +1,56 @@
#ifndef VM_H
#define VM_H

#include <stdint.h>

typedef enum vm_type
{
VM_TYPE_FUNCTION,
VM_TYPE_INTEGER,
VM_TYPE_STRING,
VM_TYPE_ARRAY,
VM_TYPE_ERROR,
VM_TYPE_NULL,
} vm_type;

typedef struct vm_var
{
vm_type type;
int isNull;
int nullable;

union
{
char* function;
int32_t integer;
char* string;
struct vm_var* array;
struct
{
char* msg;
char* code;
} error;
} data;
} vm_var;

typedef struct vm
{
vm_var* vars;
size_t numvars;
} vm;

//Initiate a VM
vm* vm_create();

//Execute
vm_var* vm_exec();

//Functions to create a variable
vm_var* vm_var_create_function(char* function, int nullable);
vm_var* vm_var_create_integer(int32_t integer, int nullable);
vm_var* vm_var_create_string(char* string, int nullable);
vm_var* vm_var_create_array(vm_var* array, int nullable);
vm_var* vm_var_create_error(char* msg, char* code, int nullable);
vm_var* vm_var_create_null();

#endif

Loading…
Cancel
Save