Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba7bd9c32d | |||
| 6f1ee46cd6 | |||
| 7643674b69 | |||
| 68c85b515b | |||
| 78d81dc260 | |||
| ec4d41edb5 | |||
| e59685413d | |||
| 66fa2a5a65 |
@@ -2,11 +2,11 @@
|
|||||||
"configVersion": 1,
|
"configVersion": 1,
|
||||||
"rock": {
|
"rock": {
|
||||||
"name": "io",
|
"name": "io",
|
||||||
"version": "0.0.1",
|
"version": "0.1.1",
|
||||||
"gccArgs": [],
|
"gccArgs": [],
|
||||||
"description": "Input / Output",
|
"description": "Input / Output",
|
||||||
"dependencies": {
|
"dependencies": {},
|
||||||
"test": "1.0.0"
|
"nativeComet": false,
|
||||||
}
|
"author": "SpookyDervish"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
234
src/file.c
Normal file
234
src/file.c
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
#include "file.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_File_INIT(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
|
||||||
|
cometSetField(fileObj, 0, args[1]); // self.path = path
|
||||||
|
|
||||||
|
char* path = cometArgString(args[1]);
|
||||||
|
char* mode = cometArgString(args[2]);
|
||||||
|
|
||||||
|
FILE* f = fopen(path, mode);
|
||||||
|
if (!f) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Failed to open \"%s\": %s", path, strerror(errno));
|
||||||
|
return cometError(vm, "IOFail", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
cometSetField(fileObj, 2, (int64_t)f); // self.ptr = f
|
||||||
|
|
||||||
|
// seek to end
|
||||||
|
fseek(f, 0L, SEEK_END);
|
||||||
|
int64_t size = ftell(f);
|
||||||
|
rewind(f);
|
||||||
|
|
||||||
|
cometSetField(fileObj, 3, size); // self.size = size
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, (int64_t)fileObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_readAll(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
int64_t length = fileObj->fields[3];
|
||||||
|
|
||||||
|
if (length == 0) {
|
||||||
|
return Success(int64_t, objectPtr, cometSerializeString(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* content = calloc(length + 1, 1);
|
||||||
|
if (!content) {
|
||||||
|
return cometError(vm, "MemoryAllocFail", "Failed to allocate memory for file content. (impl_readAll)");
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(content, length, 1, f);
|
||||||
|
|
||||||
|
// serialize string
|
||||||
|
return Success(int64_t, objectPtr, cometSerializeString(content));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_read(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[1];
|
||||||
|
|
||||||
|
int64_t amountToRead = cometArgBig(args[0]);
|
||||||
|
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
char* content = calloc(amountToRead + 1, 1);
|
||||||
|
if (!content) {
|
||||||
|
return cometError(vm, "MemoryAllocFail", "Failed to allocate memory for file content. (impl_read)");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytesRead = fread(content, amountToRead, 1, f);
|
||||||
|
if (bytesRead < amountToRead) {
|
||||||
|
if (ferror(f)) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Error while reading file: %s", strerror(errno));
|
||||||
|
return cometError(vm, "IOFail", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// serialize string
|
||||||
|
return Success(int64_t, objectPtr, cometSerializeString(content));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_readln(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
if (feof(f)) {
|
||||||
|
return Success(int64_t, objectPtr, cometSerializeString(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t read = getline(&line, &len, f);
|
||||||
|
|
||||||
|
if (read == -1) {
|
||||||
|
if (ferror(f)) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Error while reading line: %s", strerror(errno));
|
||||||
|
return cometError(vm, "IOFail", buffer);
|
||||||
|
} else {
|
||||||
|
return Success(int64_t, objectPtr, cometSerializeString(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read > 0 && line[read - 1] == '\n') {
|
||||||
|
line[read - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// serialize string
|
||||||
|
return Success(int64_t, objectPtr, cometSerializeString(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_isEOF(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, feof(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_write(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[1];
|
||||||
|
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
char* strToWrite = cometArgString(args[0]);
|
||||||
|
size_t numBytes = strlen(strToWrite);
|
||||||
|
|
||||||
|
size_t written = fwrite(strToWrite, numBytes, 1, f);
|
||||||
|
if (written < numBytes) {
|
||||||
|
if (ferror(f)) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Error while writing to file: %s", strerror(errno));
|
||||||
|
return cometError(vm, "IOFail", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_writeln(int64_t* args, CometVM* vm) {
|
||||||
|
char* strToWrite = cometArgString(args[0]);
|
||||||
|
|
||||||
|
size_t ogStrLen = strlen(strToWrite);
|
||||||
|
|
||||||
|
char* fullString = malloc( ogStrLen + 2); // 1 byte for \n, 1 byte for null
|
||||||
|
memcpy(fullString, strToWrite, ogStrLen);
|
||||||
|
fullString[ogStrLen] = '\n';
|
||||||
|
fullString[ogStrLen+1] = 0;
|
||||||
|
|
||||||
|
size_t fullStringLen = ogStrLen + 1;
|
||||||
|
|
||||||
|
CometObject* fileObj = (CometObject*)args[1];
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
size_t written = fwrite(fullString, fullStringLen, 1, f);
|
||||||
|
if (written < fullStringLen) {
|
||||||
|
if (ferror(f)) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Error while writing to file: %s", strerror(errno));
|
||||||
|
return cometError(vm, "IOFail", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_seek(int64_t* args, CometVM* vm) {
|
||||||
|
int64_t seekPos = cometArgBig(args[0]);
|
||||||
|
|
||||||
|
CometObject* fileObj = (CometObject*)args[1];
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
fseek(f, seekPos, SEEK_SET);
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_tell(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
int64_t tellTo = ftell(f);
|
||||||
|
if (tellTo == -1) {
|
||||||
|
if (ferror(f)) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Error while telling file: %s", strerror(errno));
|
||||||
|
return cometError(vm, "IOFail", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, tellTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_flush(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
fflush(f);
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_close(int64_t* args, CometVM* vm) {
|
||||||
|
CometObject* fileObj = (CometObject*)args[0];
|
||||||
|
FILE* f = (FILE*)fileObj->fields[2];
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void createFileStruct(CometEnvironment* env) {
|
||||||
|
CometStruct* fileStruct = cometDefineStruct(env, "File", NULL);
|
||||||
|
|
||||||
|
List(StructField) fields = newList(StructField);
|
||||||
|
append(fields, cometCreateField("path", cometTypeString, FIELD_READ_ONLY));
|
||||||
|
append(fields, cometCreateField("mode", cometTypeString, FIELD_READ_ONLY));
|
||||||
|
append(fields, cometCreateField("ptr", cometTypeBig, FIELD_PRIVATE));
|
||||||
|
append(fields, cometCreateField("size", cometTypeBig, FIELD_READ_ONLY));
|
||||||
|
|
||||||
|
List(externalMethodPtr) methods = newList(externalMethodPtr);
|
||||||
|
append(methods, cometDefineMethod(env, "readAll", fileStruct, FIELD_PUBLIC, cometTypeString, 0, false));
|
||||||
|
append(methods, cometDefineMethod(env, "read", fileStruct, FIELD_PUBLIC, cometTypeString, 1, false, cometTypeBig));
|
||||||
|
append(methods, cometDefineMethod(env, "readln", fileStruct, FIELD_PUBLIC, cometTypeString, 0, false));
|
||||||
|
append(methods, cometDefineMethod(env, "isEOF", fileStruct, FIELD_PUBLIC, cometTypeBool, 0, false));
|
||||||
|
append(methods, cometDefineMethod(env, "write", fileStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeString));
|
||||||
|
append(methods, cometDefineMethod(env, "writeln", fileStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeString));
|
||||||
|
append(methods, cometDefineMethod(env, "seek", fileStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeBig));
|
||||||
|
append(methods, cometDefineMethod(env, "tell", fileStruct, FIELD_PUBLIC, cometTypeBig, 0, false));
|
||||||
|
append(methods, cometDefineMethod(env, "flush", fileStruct, FIELD_PUBLIC, cometTypeVoid, 0, false));
|
||||||
|
append(methods, cometDefineMethod(env, "close", fileStruct, FIELD_PUBLIC, cometTypeVoid, 0, false));
|
||||||
|
|
||||||
|
cometSetStructFieldsAndMethods(fileStruct, fields, methods);
|
||||||
|
cometDefineConstructor(env, fileStruct, 2, false, cometTypeString, cometTypeString);
|
||||||
|
}
|
||||||
8
src/file.h
Normal file
8
src/file.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef FILE_H
|
||||||
|
#define FILE_H
|
||||||
|
|
||||||
|
#include <comet/cometlib.h>
|
||||||
|
|
||||||
|
void createFileStruct(CometEnvironment* env);
|
||||||
|
|
||||||
|
#endif
|
||||||
97
src/main.c
97
src/main.c
@@ -1,101 +1,12 @@
|
|||||||
#include <comet/cometlib.h>
|
#include <comet/cometlib.h>
|
||||||
#include <stdlib.h>
|
#include "file.h"
|
||||||
|
|
||||||
static CometType cometTypeString = cometTypeVoid;
|
|
||||||
|
|
||||||
void ensureStringType() {
|
|
||||||
if (cometTypeString.typeKind == COMET_VOID)
|
|
||||||
cometTypeString = createArrayType(cometTypeSmall, 1, (bool[]){false}, (uint64_t[]){});
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t impl_print(int64_t* args, CometVM* vm) {
|
|
||||||
ensureStringType();
|
|
||||||
|
|
||||||
CometOperand formatStringArray = deserializeValue(args[0], cometTypeString);
|
|
||||||
char* formatString = (char*)cometArrayToCArray(formatStringArray, cometTypeSmall);
|
|
||||||
|
|
||||||
size_t argIdx = 1;
|
|
||||||
|
|
||||||
for (size_t i = 0; formatString[i] != 0; i++) {
|
|
||||||
|
|
||||||
// look for '%'
|
|
||||||
if (formatString[i] == '%') {
|
|
||||||
switch (formatString[i+1]) {
|
|
||||||
case 'n': {
|
|
||||||
printf("%ld", deserializeValue(args[argIdx], cometTypeBig).imm.bigVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'f': {
|
|
||||||
printf("%f", deserializeValue(args[argIdx], cometTypeDouble).imm.doubleVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'b': {
|
|
||||||
bool boolVal = deserializeValue(args[argIdx], cometTypeBool).imm.boolVal;
|
|
||||||
printf( boolVal ? "true" : "false");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 's': {
|
|
||||||
CometOperand strArr = deserializeValue(args[argIdx], cometTypeString);
|
|
||||||
char* str = (char*)cometArrayToCArray(strArr, cometTypeSmall);
|
|
||||||
printf("%s", str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c': {
|
|
||||||
printf("%c", deserializeValue(args[argIdx], cometTypeBig).imm.smallVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
printf("%%%c", formatString[i+1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
argIdx++;
|
|
||||||
} else {
|
|
||||||
putchar(formatString[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t impl_println(int64_t* args, CometVM* vm) {
|
|
||||||
int64_t returnVal = impl_print(args, vm);
|
|
||||||
putchar('\n');
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t impl_getline(int64_t* args, CometVM* vm) {
|
|
||||||
ensureStringType();
|
|
||||||
|
|
||||||
char* userInput = NULL;
|
|
||||||
size_t numChars = 0;
|
|
||||||
|
|
||||||
int64_t result = getline(&userInput, &numChars, stdin);
|
|
||||||
if (result == -1) {
|
|
||||||
if (userInput) free(userInput);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result > 0 && userInput[result - 1] == '\n') {
|
|
||||||
userInput[result - 1] = '\0';
|
|
||||||
result--;
|
|
||||||
}
|
|
||||||
|
|
||||||
CometOperand strValue = CArrayToCometArray(userInput, result, cometTypeSmall);
|
|
||||||
free(userInput);
|
|
||||||
|
|
||||||
int64_t serializedStr = serializeValue(strValue);
|
|
||||||
|
|
||||||
return serializedStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
on_import {
|
on_import {
|
||||||
if (cometTypeString.typeKind == COMET_VOID)
|
|
||||||
cometTypeString = createArrayType(cometTypeSmall, 1, (bool[]){false}, (uint64_t[]){});
|
|
||||||
|
|
||||||
cometDefineFunc(env, "print", cometTypeSmall, 1, true, cometTypeString);
|
cometDefineFunc(env, "print", cometTypeSmall, 1, true, cometTypeString);
|
||||||
cometDefineFunc(env, "println", cometTypeSmall, 1, true, cometTypeString);
|
cometDefineFunc(env, "println", cometTypeSmall, 1, true, cometTypeString);
|
||||||
cometDefineFunc(env, "getline", cometTypeString, 0, false);
|
cometDefineFunc(env, "getline", cometTypeString, 0, false);
|
||||||
|
|
||||||
|
// define file struct
|
||||||
|
createFileStruct(env);
|
||||||
}
|
}
|
||||||
75
src/printing.c
Normal file
75
src/printing.c
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#include "printing.h"
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_print(int64_t* args, CometVM* vm) {
|
||||||
|
char* formatString = cometArgString(args[0]);
|
||||||
|
|
||||||
|
size_t argIdx = 1;
|
||||||
|
|
||||||
|
for (size_t i = 0; formatString[i] != 0; i++) {
|
||||||
|
|
||||||
|
// look for '%'
|
||||||
|
if (formatString[i] == '%') {
|
||||||
|
switch (formatString[i+1]) {
|
||||||
|
case 'n': {
|
||||||
|
printf("%ld", cometArgBig(args[argIdx]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f': {
|
||||||
|
printf("%f", cometArgDouble(args[argIdx]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'b': {
|
||||||
|
bool boolVal = cometArgBool(args[argIdx]);
|
||||||
|
printf( boolVal ? "true" : "false");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 's': {
|
||||||
|
char* str = cometArgString(args[argIdx]);
|
||||||
|
printf("%s", str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'c': {
|
||||||
|
printf("%c", cometArgSmall(args[argIdx]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("%%%c", formatString[i+1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
argIdx++;
|
||||||
|
} else {
|
||||||
|
putchar(formatString[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_println(int64_t* args, CometVM* vm) {
|
||||||
|
ResultType(int64_t, objectPtr) returnVal = impl_print(args, vm);
|
||||||
|
putchar('\n');
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_getline(int64_t* args, CometVM* vm) {
|
||||||
|
char* userInput = NULL;
|
||||||
|
size_t numChars = 0;
|
||||||
|
|
||||||
|
ssize_t result = getline(&userInput, &numChars, stdin);
|
||||||
|
if (result == -1) {
|
||||||
|
if (userInput) free(userInput);
|
||||||
|
return cometError(vm, "MemoryAllocFail", "Failed to allocate memory for string in io.getline!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result > 0 && userInput[result - 1] == '\n') {
|
||||||
|
userInput[result - 1] = '\0';
|
||||||
|
result--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t serializedStr = cometSerializeString(userInput);
|
||||||
|
free(userInput);
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, serializedStr);
|
||||||
|
}
|
||||||
10
src/printing.h
Normal file
10
src/printing.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef PRINTING_H
|
||||||
|
#define PRINTING_H
|
||||||
|
|
||||||
|
#include <comet/cometlib.h>
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_print(int64_t* args, CometVM* vm);
|
||||||
|
ResultType(int64_t, objectPtr) impl_println(int64_t* args, CometVM* vm);
|
||||||
|
ResultType(int64_t, objectPtr) impl_getline(int64_t* args, CometVM* vm);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user