Skip to content

Commit

Permalink
Merge pull request #320 from dictu-lang/develop
Browse files Browse the repository at this point in the history
Release 0.12.0
  • Loading branch information
Jason2605 authored Nov 10, 2020
2 parents fa60667 + 44785c7 commit 06c6627
Show file tree
Hide file tree
Showing 75 changed files with 1,228 additions and 383 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
examples
.github
docs
README.md
LICENSE
14 changes: 14 additions & 0 deletions Docker/DictuAlpineDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM alpine

WORKDIR Dictu

RUN apk add make curl-dev gcc libc-dev --no-cache

COPY . .

RUN make dictu \
&& cp dictu /usr/bin/ \
&& dictu tests/runTests.du \
&& rm -rf *

CMD ["dictu"]
18 changes: 18 additions & 0 deletions Docker/DictuUbuntuDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM ubuntu

WORKDIR Dictu

RUN apt update \
&& apt install -y --no-install-recommends build-essential \
&& apt-get update \
&& apt-get install -y --no-install-recommends libcurl4-gnutls-dev\
&& rm -rf /var/lib/apt/lists/*

COPY . .

RUN make dictu \
&& cp dictu /usr/bin/ \
&& dictu tests/runTests.du \
&& rm -rf *

CMD ["dictu"]
35 changes: 35 additions & 0 deletions Docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Dictu Docker

### Building the Docker image

Make sure you have Docker installed on your system. Refer to [Docker installation](https://docs.docker.com/engine/install/).

To build the Docker image of Dictu, clone the repository and change directory into `Dictu`.

Run the following command from the **root of the project** i.e, the `Dictu` folder by default.

To build the *Alpine* version of Dictu -

```bash
$ docker build -t dictu:alpine -f Docker/DictuAlpineDockerfile .
```

To build the *Ubuntu* version of Dictu -

```bash
$ docker build -t dictu:ubuntu -f Docker/DictuUbuntuDockerfile .
```

To start a REPL from this image, run - (Replace the tag with the appropriate version, i.e, alpine or ubuntu)

```bash
$ docker run -it dictu:ubuntu
```

> The image built can be used in other docker images as a base image for running dictu files. Make sure you have the image built locally.
```Dockerfile
FROM dictu:ubuntu
COPY example.du .
RUN dictu example.du
```
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ $ make dictu DISABLE_HTTP=1
$ ./dictu examples/guessingGame.du
```

### Docker Installation

Refer to [Dictu Docker](https://github.com/dictu-lang/Dictu/blob/develop/Docker/README.md)


## Example program
```js
var userInput;
Expand Down
2 changes: 2 additions & 0 deletions c/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <stddef.h>
#include <stdint.h>

#define UNUSED(__x__) (void) __x__

#define NAN_TAGGING
#define DEBUG_PRINT_CODE
#define DEBUG_TRACE_EXECUTION
Expand Down
137 changes: 125 additions & 12 deletions c/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static void advance(Parser *parser) {
parser->previous = parser->current;

for (;;) {
parser->current = scanToken();
parser->current = scanToken(&parser->scanner);
if (parser->current.type != TOKEN_ERROR) break;

errorAtCurrent(parser, parser->current.start);
Expand Down Expand Up @@ -672,7 +672,7 @@ static void number(Compiler *compiler, bool canAssign) {

// We allocate the whole range for the worst case.
// Also account for the null-byte.
char* buffer = (char *)malloc((compiler->parser->previous.length + 1) * sizeof(char));
char* buffer = ALLOCATE(compiler->parser->vm, char, compiler->parser->previous.length + 1);
char* current = buffer;

// Strip it of any underscores.
Expand All @@ -692,7 +692,7 @@ static void number(Compiler *compiler, bool canAssign) {
emitConstant(compiler, NUMBER_VAL(value));

// Free the malloc'd buffer.
free(buffer);
FREE_ARRAY(compiler->parser->vm, char, buffer, compiler->parser->previous.length + 1);
}

static void or_(Compiler *compiler, bool canAssign) {
Expand Down Expand Up @@ -781,13 +781,14 @@ static void string(Compiler *compiler, bool canAssign) {

Parser *parser = compiler->parser;

char *string = malloc(sizeof(char) * parser->previous.length - 1);
char *string = ALLOCATE(parser->vm, char, parser->previous.length - 1);

memcpy(string, parser->previous.start + 1, parser->previous.length - 2);
int length = parseString(string, parser->previous.length - 2);
string[length] = '\0';

emitConstant(compiler, OBJ_VAL(copyString(parser->vm, string, length)));
free(string);
emitConstant(compiler, OBJ_VAL(takeString(parser->vm, string, length)));
parser->vm->bytesAllocated -= parser->previous.length - 2 - length;
}

static void list(Compiler *compiler, bool canAssign) {
Expand Down Expand Up @@ -1189,6 +1190,7 @@ ParseRule rules[] = {
{NULL, NULL, PREC_NONE}, // TOKEN_WITH
{NULL, NULL, PREC_NONE}, // TOKEN_EOF
{NULL, NULL, PREC_NONE}, // TOKEN_IMPORT
{NULL, NULL, PREC_NONE}, // TOKEN_FROM
{NULL, NULL, PREC_NONE}, // TOKEN_ERROR
};

Expand Down Expand Up @@ -1276,6 +1278,11 @@ static void method(Compiler *compiler) {
// Setup function and parse parameters
beginFunction(compiler, &fnCompiler, TYPE_ABSTRACT);
endCompiler(&fnCompiler);

if (check(compiler, TOKEN_LEFT_BRACE)) {
error(compiler->parser, "Abstract methods can not have an implementation.");
return;
}
}

emitBytes(compiler, OP_METHOD, constant);
Expand Down Expand Up @@ -1676,14 +1683,17 @@ static void importStatement(Compiler *compiler) {
compiler->parser->previous.length - 2)));

emitBytes(compiler, OP_IMPORT, importConstant);
emitByte(compiler, OP_POP);

if (match(compiler, TOKEN_AS)) {
uint8_t importName = parseVariable(compiler, "Expect import alias.", false);
emitByte(compiler, OP_IMPORT_VARIABLE);
defineVariable(compiler, importName, false);
}
} else {
uint8_t importName = parseVariable(compiler, "Expect import identifier.", false);
consume(compiler, TOKEN_IDENTIFIER, "Expect import identifier.");
uint8_t importName = identifierConstant(compiler, &compiler->parser->previous);
declareVariable(compiler, &compiler->parser->previous);

int index = findBuiltinModule(
(char *)compiler->parser->previous.start,
Expand All @@ -1704,6 +1714,104 @@ static void importStatement(Compiler *compiler) {
emitByte(compiler, OP_IMPORT_END);
}

static void fromImportStatement(Compiler *compiler) {
if (match(compiler, TOKEN_STRING)) {
int importConstant = makeConstant(compiler, OBJ_VAL(copyString(
compiler->parser->vm,
compiler->parser->previous.start + 1,
compiler->parser->previous.length - 2)));

consume(compiler, TOKEN_IMPORT, "Expect 'import' after import path.");
emitBytes(compiler, OP_IMPORT, importConstant);
emitByte(compiler, OP_POP);

uint8_t variables[255];
Token tokens[255];
int varCount = 0;

do {
consume(compiler, TOKEN_IDENTIFIER, "Expect variable name.");
tokens[varCount] = compiler->parser->previous;
variables[varCount] = identifierConstant(compiler, &compiler->parser->previous);
varCount++;

if (varCount > 255) {
error(compiler->parser, "Cannot have more than 255 variables.");
}
} while (match(compiler, TOKEN_COMMA));

emitBytes(compiler, OP_IMPORT_FROM, varCount);

for (int i = 0; i < varCount; ++i) {
emitByte(compiler, variables[i]);
}

// This needs to be two separate loops as we need
// all the variables popped before defining.
if (compiler->scopeDepth == 0) {
for (int i = varCount - 1; i >= 0; --i) {
defineVariable(compiler, variables[i], false);
}
} else {
for (int i = 0; i < varCount; ++i) {
declareVariable(compiler, &tokens[i]);
defineVariable(compiler, 0, false);
}
}

emitByte(compiler, OP_IMPORT_END);
} else {
consume(compiler, TOKEN_IDENTIFIER, "Expect import identifier.");
uint8_t importName = identifierConstant(compiler, &compiler->parser->previous);

int index = findBuiltinModule(
(char *)compiler->parser->previous.start,
compiler->parser->previous.length
);

consume(compiler, TOKEN_IMPORT, "Expect 'import' after identifier");

if (index == -1) {
error(compiler->parser, "Unknown module");
}

uint8_t variables[255];
Token tokens[255];
int varCount = 0;

do {
consume(compiler, TOKEN_IDENTIFIER, "Expect variable name.");
tokens[varCount] = compiler->parser->previous;
variables[varCount] = identifierConstant(compiler, &compiler->parser->previous);
varCount++;

if (varCount > 255) {
error(compiler->parser, "Cannot have more than 255 variables.");
}
} while (match(compiler, TOKEN_COMMA));

emitBytes(compiler, OP_IMPORT_BUILTIN_VARIABLE, index);
emitBytes(compiler, importName, varCount);

for (int i = 0; i < varCount; ++i) {
emitByte(compiler, variables[i]);
}

if (compiler->scopeDepth == 0) {
for (int i = varCount - 1; i >= 0; --i) {
defineVariable(compiler, variables[i], false);
}
} else {
for (int i = 0; i < varCount; ++i) {
declareVariable(compiler, &tokens[i]);
defineVariable(compiler, 0, false);
}
}
}

consume(compiler, TOKEN_SEMICOLON, "Expect ';' after import.");
}

static void whileStatement(Compiler *compiler) {
Loop loop;
loop.start = currentChunk(compiler)->count;
Expand Down Expand Up @@ -1794,6 +1902,8 @@ static void statement(Compiler *compiler) {
withStatement(compiler);
} else if (match(compiler, TOKEN_IMPORT)) {
importStatement(compiler);
} else if (match(compiler, TOKEN_FROM)) {
fromImportStatement(compiler);
} else if (match(compiler, TOKEN_BREAK)) {
breakStatement(compiler);
} else if (match(compiler, TOKEN_WHILE)) {
Expand All @@ -1808,8 +1918,8 @@ static void statement(Compiler *compiler) {

if (check(compiler, TOKEN_RIGHT_BRACE)) {
if (check(compiler, TOKEN_SEMICOLON)) {
backTrack();
backTrack();
backTrack(&parser->scanner);
backTrack(&parser->scanner);
parser->current = previous;
expressionStatement(compiler);
return;
Expand All @@ -1818,7 +1928,7 @@ static void statement(Compiler *compiler) {

if (check(compiler, TOKEN_COLON)) {
for (int i = 0; i < parser->current.length + parser->previous.length; ++i) {
backTrack();
backTrack(&parser->scanner);
}

parser->current = previous;
Expand All @@ -1828,7 +1938,7 @@ static void statement(Compiler *compiler) {

// Reset the scanner to the previous position
for (int i = 0; i < parser->current.length; ++i) {
backTrack();
backTrack(&parser->scanner);
}

// Reset the parser
Expand All @@ -1852,7 +1962,10 @@ ObjFunction *compile(VM *vm, ObjModule *module, const char *source) {
parser.panicMode = false;
parser.module = module;

initScanner(source);
Scanner scanner;
initScanner(&scanner, source);
parser.scanner = scanner;

Compiler compiler;
initCompiler(&parser, &compiler, NULL, TYPE_TOP_LEVEL);

Expand Down
1 change: 1 addition & 0 deletions c/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef struct Loop {

typedef struct {
VM *vm;
Scanner scanner;
Token current;
Token previous;
bool hadError;
Expand Down
10 changes: 3 additions & 7 deletions c/datatypes/files.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "files.h"
#include "../vm.h"
#include "../memory.h"

static Value writeFile(VM *vm, int argCount, Value *args) {
Expand Down Expand Up @@ -72,24 +71,21 @@ static Value readFullFile(VM *vm, int argCount, Value *args) {
fseek(file->file, currentPosition, SEEK_SET);
}

char *buffer = (char *) malloc(fileSize + 1);
char *buffer = ALLOCATE(vm, char, fileSize + 1);
if (buffer == NULL) {
runtimeError(vm, "Not enough memory to read \"%s\".\n", file->path);
return EMPTY_VAL;
}

size_t bytesRead = fread(buffer, sizeof(char), fileSize, file->file);
if (bytesRead < fileSize && !feof(file->file)) {
free(buffer);
FREE_ARRAY(vm, char, buffer, fileSize + 1);
runtimeError(vm, "Could not read file \"%s\".\n", file->path);
return EMPTY_VAL;
}

buffer[bytesRead] = '\0';
Value ret = OBJ_VAL(copyString(vm, buffer, bytesRead));

free(buffer);
return ret;
return OBJ_VAL(takeString(vm, buffer, bytesRead));
}

static Value readLineFile(VM *vm, int argCount, Value *args) {
Expand Down
Loading

0 comments on commit 06c6627

Please sign in to comment.