Skip to content

Commit

Permalink
Added modifiers (readonly, private)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vardan2009 committed Aug 22, 2024
1 parent 0646e93 commit 8f0d3bf
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 28 deletions.
27 changes: 14 additions & 13 deletions eiger/Execution/BuiltInTypes/Value.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace EigerLang.Execution.BuiltInTypes;

public class Value(string _filename, int _line, int _pos)

Check warning on line 6 in eiger/Execution/BuiltInTypes/Value.cs

View workflow job for this annotation

GitHub Actions / build

'Value' overrides Object.Equals(object o) but does not override Object.GetHashCode()

Check warning on line 6 in eiger/Execution/BuiltInTypes/Value.cs

View workflow job for this annotation

GitHub Actions / build

'Value' overrides Object.Equals(object o) but does not override Object.GetHashCode()
{
public bool isReadonly = false;
public List<string> modifiers = [];
public string filename = _filename;
public int line = _line, pos = _pos;

Expand Down Expand Up @@ -101,19 +101,20 @@ public virtual Value GetLength()

public virtual Value GetAttr(ASTNode attr)
{
Value retVal;
if (attr.type == NodeType.AttrAccess)
{
return GetAttr(attr.children[0]).GetAttr(attr.children[1]);
}
if (attr.value == "asString")
{
return new String(filename, line, pos, ToString() ?? "");
}
if (attr.value == "length")
{
return GetLength();
}
throw new EigerError(filename, line, pos, "Attribute not found", EigerError.ErrorType.RuntimeError);
retVal = GetAttr(attr.children[0]).GetAttr(attr.children[1]);
else if (attr.value == "asString")
retVal = new String(filename, line, pos, ToString() ?? "");
else if (attr.value == "length")
retVal = GetLength();
else
throw new EigerError(filename, line, pos, "Attribute not found", EigerError.ErrorType.RuntimeError);

if (retVal.modifiers.Contains("private"))
throw new EigerError(filename, line, pos, "Attribute is private", EigerError.ErrorType.RuntimeError);

return retVal;
}

public virtual void SetAttr(ASTNode attr, Value val)
Expand Down
45 changes: 33 additions & 12 deletions eiger/Execution/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ class Interpreter
public static BuiltInFunctions.ExitFunction exitFunction = new();
public static Number fgColor = new("<std>", 0, 0, (int)ConsoleColor.Gray)
{
isReadonly = true
modifiers = ["readonly"]
};
public static Number bgColor = new("<std>", 0, 0, (int)ConsoleColor.Black)
{
isReadonly = true
modifiers = ["readonly"]
};

// global symbol table
Expand Down Expand Up @@ -267,14 +267,20 @@ public static (bool, bool, Value) VisitBlockNode(ASTNode node, Dictionary<string
// LetNode: variableName
// -- initialValue (optional)

if (symbolTable.ContainsKey(node.value))
throw new EigerError(node.filename, node.line, node.pos, $"Variable {node.value} already declared", EigerError.ErrorType.RuntimeError);
dynamic?[] pack = node.value ?? new dynamic?[2];
string varName = pack[1] ?? "";
List<string> modifiers = pack[0] ?? new List<string>();

if (symbolTable.ContainsKey(varName))
throw new EigerError(node.filename, node.line, node.pos, $"Variable {varName} already declared", EigerError.ErrorType.RuntimeError);

Value v = node.children.Count == 1
? VisitNode(node.children[0], symbolTable).Item3
: new Nix(node.filename, node.line, node.pos);

symbolTable.Add(node.value, v);
v.modifiers = modifiers;

symbolTable.Add(varName, v);
return (false, false, v);
}

Expand Down Expand Up @@ -347,7 +353,9 @@ public static (bool, bool, Value) VisitBlockNode(ASTNode node, Dictionary<string
// -- ...

// get function name
string funcName = node.value ?? "";
dynamic?[] pack = node.value ?? new dynamic?[2];
string funcName = pack[1] ?? "";
List<string> modifiers = pack[0] ?? new List<string>();

// a symbol with that name already exists
if (symbolTable.ContainsKey(funcName) && funcName != "")
Expand All @@ -368,11 +376,16 @@ public static (bool, bool, Value) VisitBlockNode(ASTNode node, Dictionary<string
argnames.Add(node.children[i].value);
}

Function result = new Function(node, funcName, argnames, root, symbolTable)
{
modifiers = modifiers
};

// add the function to the current scope
if (funcName != "")
symbolTable[funcName] = new Function(node, funcName, argnames, root, symbolTable);
symbolTable[funcName] = result;

return (false, false, new Function(node, funcName, argnames, root, symbolTable));
return (false, false, result);
}

// Visit inline function definition node
Expand All @@ -386,7 +399,9 @@ public static (bool, bool, Value) VisitBlockNode(ASTNode node, Dictionary<string
// -- ...

// get function name
string funcName = node.value ?? "";
dynamic?[] pack = node.value ?? new dynamic?[2];
string funcName = pack[1] ?? "";
List<string> modifiers = pack[0] ?? new List<string>();

if (symbolTable.ContainsKey(funcName) && funcName != "")
throw new EigerError(node.filename, node.line, node.pos, $"{funcName} already declared", EigerError.ErrorType.RuntimeError);
Expand All @@ -406,7 +421,10 @@ public static (bool, bool, Value) VisitBlockNode(ASTNode node, Dictionary<string
argnames.Add(node.children[i].value);
}

InlineFunction f = new InlineFunction(node, funcName, argnames, root, symbolTable);
InlineFunction f = new InlineFunction(node, funcName, argnames, root, symbolTable)
{
modifiers = modifiers
};

// add the function to the current scope
if (funcName != "")
Expand Down Expand Up @@ -473,7 +491,7 @@ public static (bool, bool, Value) VisitBlockNode(ASTNode node, Dictionary<string
private static Value HandleAssignment(ASTNode node, Value rightSide, Dictionary<string, Value> symbolTable)
{
Value leftValue = GetSymbol(symbolTable, node.children[0]);
if (leftValue.isReadonly)
if (leftValue.modifiers.Contains("readonly"))
throw new EigerError(leftValue.filename, leftValue.line, leftValue.pos, $"{leftValue} is read-only!", EigerError.ErrorType.RuntimeError);

SetSymbol(symbolTable, node.children[0], rightSide);
Expand All @@ -484,7 +502,7 @@ private static Value HandleCompoundAssignment(ASTNode node, Value rightSide, Dic
{
Value leftValue = GetSymbol(symbolTable, node.children[0]);
Value newValue = operation(leftValue, rightSide);
if (leftValue.isReadonly)
if (leftValue.modifiers.Contains("readonly"))
throw new EigerError(leftValue.filename, leftValue.line, leftValue.pos, $"{leftValue} is read-only!", EigerError.ErrorType.RuntimeError);
else
SetSymbol(symbolTable, node.children[0], newValue);
Expand Down Expand Up @@ -548,6 +566,9 @@ private static (bool, bool, Value) VisitAttrAccessNode(ASTNode node, Dictionary<
currentNode = currentNode.children[1];
}

if (v.modifiers.Contains("private"))
throw new EigerError(node.filename, node.line, node.pos, "Attribute is private", EigerError.ErrorType.RuntimeError);

if (v is BaseFunction f && currentNode.type == NodeType.FuncCall)
{
List<Value> args = []; // prepare a list for args
Expand Down
39 changes: 36 additions & 3 deletions eiger/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public class Parser(List<Token> tokens)
TokenType.EQ, TokenType.PLUSEQ,TokenType.MINUSEQ,TokenType.MULEQ,TokenType.DIVEQ,TokenType.EQEQ, TokenType.NEQEQ,TokenType.GT, TokenType.LT, TokenType.GTE, TokenType.LTE,
};

readonly List<string> varModifiers = new()
{
"readonly", "private"
};

string path = "<stdin>";

// parse the root
Expand Down Expand Up @@ -149,14 +154,28 @@ ASTNode FuncDefStatement(bool includeName = true)
Token funcTok = Peek();
Match(TokenType.IDENTIFIER, "func");

List<string> modifiers = [];

while (Peek().type == TokenType.IDENTIFIER && varModifiers.Contains(Peek().value))
{
string modifier = Peek().value ?? throw new EigerError(path, Peek().line, Peek().pos, $"Modifier has no value", EigerError.ErrorType.RuntimeError);

if (modifiers.Contains(modifier))
throw new EigerError(path, Peek().line, Peek().pos, $"Double modifier {modifier}", EigerError.ErrorType.RuntimeError);
else
modifiers.Add(modifier);

Advance();
}

// get func name
string funcName = "";

if (includeName)
funcName = Advance().value ?? "";

// create func def node
ASTNode node = new(NodeType.FuncDef, funcName, funcTok.line, funcTok.pos, path);
ASTNode node = new(NodeType.FuncDef, new dynamic?[2] { modifiers, funcName }, funcTok.line, funcTok.pos, path);
// create list for args
List<ASTNode> args = [];

Expand Down Expand Up @@ -368,12 +387,26 @@ ASTNode LetStatement()
Token letToken = Peek();
Match(TokenType.IDENTIFIER, "let");

List<string> modifiers = [];

while (Peek().type == TokenType.IDENTIFIER && varModifiers.Contains(Peek().value))
{
string modifier = Peek().value ?? throw new EigerError(path, Peek().line, Peek().pos, $"Modifier has no value", EigerError.ErrorType.RuntimeError);

if (modifiers.Contains(modifier))
throw new EigerError(path, Peek().line, Peek().pos, $"Double modifier {modifier}", EigerError.ErrorType.RuntimeError);
else
modifiers.Add(modifier);

Advance();
}

Token variableName = Advance();

ASTNode letNode = new ASTNode(NodeType.Let, variableName.value, letToken.line, letToken.pos, path);
ASTNode letNode = new(NodeType.Let, new dynamic?[2] { modifiers, variableName.value }, letToken.line, letToken.pos, path);

// if the variable has an initial value (let x = 10)
if(Peek().type == TokenType.EQ)
if (Peek().type == TokenType.EQ)
{
Match(TokenType.EQ);
letNode.AddChild(Expr());
Expand Down

0 comments on commit 8f0d3bf

Please sign in to comment.