Skip to content

Commit

Permalink
Fix bug with missing 'this.' prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed Nov 19, 2023
1 parent 94211e8 commit a5b956b
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .run/spice.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O2 -ir ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -d --disable-verifier ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_LIB_DIR" value="D:/LLVM/build-release/lib" />
<env name="LLVM_INCLUDE_DIR" value="D:/LLVM/llvm/include" />
Expand Down
7 changes: 2 additions & 5 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
//import "../../src-bootstrap/reader/reader";
import "std/type/int";
import "../../src-bootstrap/reader/reader";

f<int> main() {
//Reader reader = Reader("./test.spice");
String str = toString(123);
printf("%s", str);
Reader reader = Reader("./test.spice");
}
19 changes: 13 additions & 6 deletions media/test-project/test2.spice
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
public type Driveable interface {
public p drive(int);
public f<bool> isDriving();
import "std/type/result";
import "std/type/error";

type FilePtr alias byte*;
public type File struct {
FilePtr* filePtr
}

#[test]
f<bool> testDriveable() {
return true;
// Link external functions
ext f<FilePtr*> fopen(string, string);

public f<Result<File>> openFile(string path, string mode) {
FilePtr* fp = fopen(path, mode);
File file = File{fp};
return fp != nil<FilePtr*> ? ok(file) : err(file, Error("Failed to open file"));
}
6 changes: 3 additions & 3 deletions src-bootstrap/reader/code-loc.spice
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public f<String> CodeLoc.toString() {
*/
public f<String> CodeLoc.toPrettyString() {
String codeLocStr = String(toString(this.line));
if this.sourceFilePath.empty() {
return toString(line) + ":" + toString(this.col);
if len(this.sourceFilePath) == 0 {
return toString(this.line) + ":" + toString(this.col);
}
return this.sourceFilePath + ":" + toString(this.line) + ":" + toString(this.col);
}
Expand All @@ -52,5 +52,5 @@ public f<String> CodeLoc.toPrettyLineAndColumn() {
}

public f<bool> operator==(const CodeLoc &lhs, const CodeLoc &rhs) {
return /*lhs.sourceFilePath == rhs.sourceFilePath && */lhs.line == rhs.line && lhs.col == rhs.col;
return lhs.sourceFilePath == rhs.sourceFilePath && lhs.line == rhs.line && lhs.col == rhs.col;
}
20 changes: 10 additions & 10 deletions src-bootstrap/reader/reader.spice
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
// Imports
// Std imports
import "std/io/filepath";
import "std/io/file";
import "std/type/result";
import "std/type/error";

// Own import
import "../reader/code-loc";

public type Reader struct {
File file
string filename
char curChar = '\0'
bool moreToRead = true
unsigned long line = 1l
unsigned long col = 0l
}

public p Reader.ctor(const string inputFileName) {
this.filename = inputFileName;
Result<File> result = openFile(inputFileName, MODE_READ);
this.file = result.unwrap();
if !file.isOpen() {

if !result.isOk() {
panic(Error("Source file cannot be opened"));
}
this.file = result.unwrap();
}

public p Reader.dtor() {
file.close();
this.file.close();
}

/**
Expand All @@ -49,9 +51,7 @@ public f<CodeLoc> Reader.getCodeLoc() {
*/
public p Reader.advance() {
assert !this.isEOF();
if !this.file.get(this.curChar) {
this.moreToRead = false;
}
this.curChar = (char) this.file.readChar();
if this.curChar == '\n' {
this.line++;
this.col = 0l;
Expand All @@ -76,5 +76,5 @@ public p Reader.expect(char c) {
* @return At the end or not
*/
public f<bool> Reader.isEOF() {
return !this.moreToRead;
return this.file.isEOF();
}
5 changes: 5 additions & 0 deletions src/global/GlobalResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ GlobalResourceManager::GlobalResourceManager(const CliOptions &cliOptions)
ltoModule = std::make_unique<llvm::Module>(LTO_FILE_NAME, context);
}

GlobalResourceManager::~GlobalResourceManager() {
// Cleanup all global LLVM resources
llvm::llvm_shutdown();
}

SourceFile *GlobalResourceManager::createSourceFile(SourceFile *parent, const std::string &dependencyName,
const std::filesystem::path &path, bool isStdFile) {
// Check if the source file was already added (e.g. by another source file that imports it)
Expand Down
1 change: 1 addition & 0 deletions src/global/GlobalResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class GlobalResourceManager {
// Constructors
explicit GlobalResourceManager(const CliOptions &cliOptions);
GlobalResourceManager(const GlobalResourceManager &) = delete;
~GlobalResourceManager();

// Public methods
SourceFile *createSourceFile(SourceFile *parent, const std::string &dependencyName, const std::filesystem::path &path,
Expand Down
13 changes: 12 additions & 1 deletion src/typechecker/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,8 +1502,14 @@ std::any TypeChecker::visitFctCall(FctCallNode *node) {
}

// Retrieve entry of the first fragment
SymbolTableEntry *firstFragEntry = currentScope->lookup(node->functionNameFragments.front());
const std::string &firstFrag = node->functionNameFragments.front();
SymbolTableEntry *firstFragEntry = currentScope->lookup(firstFrag);
if (firstFragEntry) {
// Check if we have seen a 'this.' prefix, because the generator needs that
if (firstFragEntry->scope->type == ScopeType::STRUCT && firstFrag != THIS_VARIABLE_NAME)
SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE,
"The symbol '" + firstFrag + "' could not be found. Missing 'this.' prefix?")

firstFragEntry->used = true;
// Decide of which type the function call is
const SymbolType &baseType = firstFragEntry->getType().getBaseType();
Expand Down Expand Up @@ -2232,6 +2238,11 @@ std::any TypeChecker::visitCustomDataType(CustomDataTypeNode *node) {
SymbolType symbolType = *genericType;
if (typeMapping.contains(firstFragment))
symbolType = typeMapping.at(firstFragment);

// Check if the replacement is a String type
if (!isImported && symbolType.isStringObj() && !sourceFile->isStringRT())
sourceFile->requestRuntimeModule(STRING_RT);

return node->setEvaluatedSymbolType(symbolType, manIdx);
}

Expand Down
3 changes: 2 additions & 1 deletion src/typechecker/TypeCheckerImplicit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ void TypeChecker::createDefaultDtorIfRequired(const Struct &spiceStruct, Scope *
createDefaultStructMethod(spiceStruct, DTOR_FUNCTION_NAME, {});

// Request memory runtime if we have fields, that are allocated on the heap
if (hasHeapFields) {
// The string runtime does not use it, but allocates manually to avoid circular dependencies
if (hasHeapFields && !sourceFile->isStringRT()) {
SourceFile *memoryRT = sourceFile->requestRuntimeModule(MEMORY_RT);
assert(memoryRT != nullptr);
Scope *matchScope = memoryRT->globalScope.get();
Expand Down
42 changes: 33 additions & 9 deletions std/io/file_linux.spice
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,28 @@ public f<long> File.getSize() {
return size;
}

/**
* Checks if the end of the file is reached.
*
* @return EOF reached / not reached
*/
public f<bool> File.isEOF() {
return this.readChar() == EOF;
}

/**
* Reads a whole file from a given path.
*
* @return Content in form of a string
*/
public f<String> readFile(string path) {
public f<Result<String>> readFile(string path) {
// Open the file in read mode
File file = openFile(path, MODE_READ);
Result<File> fileResult = openFile(path, MODE_READ);
// Check for errors
if (fileResult.isErr()) {
return err(String(), fileResult.getErr());
}
File file = fileResult.unwrap();
// Read from the file char by char
int buffer;
String output = String();
Expand All @@ -132,37 +146,47 @@ public f<String> readFile(string path) {
}
// Close the file
file.close();
return output;
return ok(output);
}

/**
* Writes a string to a file at a given path.
*
* @return Result code of the write operation: 0 = successful, -1 = failed
*/
public f<int> writeFile(string path, string content) {
public f<Result<int>> writeFile(string path, string content) {
// Open the file in write mode
File file = openFile(path, MODE_WRITE);
Result<File> fileResult = openFile(path, MODE_WRITE);
// Check for errors
if (fileResult.isErr()) {
return err(0, fileResult.getErr());
}
File file = fileResult.unwrap();
// Write the string to the file
int resultCode = file.writeString(content);
// Close the file
file.close();
return resultCode;
return ok(resultCode);
}

/**
* Returns the size of the file at the given paths in bytes.
*
* @return File size in bytes
*/
public f<long> getFileSize(string path) {
public f<Result<long>> getFileSize(string path) {
// Open the file in read mode
File file = openFile(path, MODE_READ);
Result<File> fileResult = openFile(path, MODE_READ);
// Check for errors
if (fileResult.isErr()) {
return err(0l, fileResult.getErr());
}
File file = fileResult.unwrap();
// Get the file size
long size = file.getSize();
// Close the file
file.close();
return size;
return ok(size);
}

/**
Expand Down
49 changes: 37 additions & 12 deletions std/io/file_windows.spice
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const int SEEK_SET = 0;
const int SEEK_CUR = 1;
const int SEEK_END = 2;

public type FilePtr alias byte*;
type FilePtr alias byte*;

public type File struct {
FilePtr* filePtr
Expand Down Expand Up @@ -60,7 +60,8 @@ public f<int> createFile(string path) {
*/
public f<Result<File>> openFile(string path, string mode) {
FilePtr* fp = fopen(path, mode);
return fp != nil<FilePtr*> ? ok(fp) : err(fp, Error("Failed to open file '" + path + "'"));
File file = File{fp};
return fp != nil<FilePtr*> ? ok(file) : err(file, Error("Failed to open file"));
}

/**
Expand Down Expand Up @@ -116,14 +117,28 @@ public f<long> File.getSize() {
return size;
}

/**
* Checks if the end of the file is reached.
*
* @return EOF reached / not reached
*/
public f<bool> File.isEOF() {
return this.readChar() == EOF;
}

/**
* Reads a whole file from a given path.
*
* @return Content in form of a string
*/
public f<String> readFile(string path) {
public f<Result<String>> readFile(string path) {
// Open the file in read mode
File file = openFile(path, MODE_READ);
Result<File> fileResult = openFile(path, MODE_READ);
// Check for errors
if !fileResult.isOk() {
return err(String(), fileResult.getErr());
}
File file = fileResult.unwrap();
// Read from the file char by char
int buffer;
String output = String();
Expand All @@ -132,37 +147,47 @@ public f<String> readFile(string path) {
}
// Close the file
file.close();
return output;
return ok(output);
}

/**
* Writes a string to a file at a given path.
*
* @return Result code of the write operation: 0 = successful, -1 = failed
*/
public f<int> writeFile(string path, string content) {
public f<Result<int>> writeFile(string path, string content) {
// Open the file in write mode
File file = openFile(path, MODE_WRITE);
Result<File> fileResult = openFile(path, MODE_WRITE);
// Check for errors
if !fileResult.isOk() {
return err(0, fileResult.getErr());
}
File file = fileResult.unwrap();
// Write the string to the file
int resultCode = file.writeString(content);
// Close the file
file.close();
return resultCode;
return ok(resultCode);
}

/**
* Returns the size of the file at the given paths in bytes.
*
* @return File size in bytes
*/
public f<long> getFileSize(string path) {
public f<Result<long>> getFileSize(string path) {
// Open the file in read mode
File file = openFile(path, MODE_READ);
// Get the file size
Result<File> fileResult = openFile(path, MODE_READ);
// Check for errors
if !fileResult.isOk() {
return err(0l, fileResult.getErr());
}
File file = fileResult.unwrap();
// Get the file file
long size = file.getSize();
// Close the file
file.close();
return size;
return ok(size);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions std/runtime/memory_rt.spice
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public f<Result<heap byte*>> sRealloc(heap byte* ptr, unsigned long size) {
* @return A pointer to the copied block, or an error if the copy failed.
*/
public f<Result<heap byte*>> sCopy(heap byte* oldPtr, heap byte* newPtr, unsigned long size) {
if oldPtr == nil<heap byte*> | newPtr == nil<heap byte*> {
return err(nil<heap byte*>, "Cannot copy from or to nil pointer!");
}
memcpy(newPtr, oldPtr, size);
return ok(newPtr);
}
Expand All @@ -51,6 +54,7 @@ public f<Result<heap byte*>> sCopy(heap byte* oldPtr, heap byte* newPtr, unsigne
* @param ptr The pointer to the block to free.
*/
public p sDealloc(heap byte*& ptr) {
if ptr == nil<heap byte*> { return; }
free(ptr);
ptr = nil<heap byte*>; // Zero out to prevent accidental double frees
}
Loading

0 comments on commit a5b956b

Please sign in to comment.