casting
This commit is contained in:
7
src/compiler/Nub.Lang/Frontend/Parsing/CastNode.cs
Normal file
7
src/compiler/Nub.Lang/Frontend/Parsing/CastNode.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Nub.Lang.Frontend.Parsing;
|
||||
|
||||
public class CastNode(NubType targetType, ExpressionNode expression) : ExpressionNode
|
||||
{
|
||||
public NubType TargetType { get; } = targetType;
|
||||
public ExpressionNode Expression { get; } = expression;
|
||||
}
|
||||
@@ -304,53 +304,70 @@ public class Parser
|
||||
}
|
||||
|
||||
private ExpressionNode ParsePrimaryExpression()
|
||||
{
|
||||
var token = ExpectToken();
|
||||
switch (token)
|
||||
{
|
||||
var token = ExpectToken();
|
||||
switch (token)
|
||||
case LiteralToken literal:
|
||||
{
|
||||
case LiteralToken literal:
|
||||
return new LiteralNode(literal.Value, literal.Type);
|
||||
}
|
||||
case IdentifierToken identifier:
|
||||
{
|
||||
return ParseExpressionIdentifier(identifier);
|
||||
}
|
||||
case SymbolToken symbolToken:
|
||||
{
|
||||
switch (symbolToken.Symbol)
|
||||
{
|
||||
return new LiteralNode(literal.Value, literal.Type);
|
||||
}
|
||||
case IdentifierToken identifier:
|
||||
{
|
||||
return ParseExpressionIdentifier(identifier);
|
||||
}
|
||||
case SymbolToken symbolToken:
|
||||
{
|
||||
switch (symbolToken.Symbol)
|
||||
case Symbol.OpenParen:
|
||||
{
|
||||
case Symbol.OpenParen:
|
||||
// This is ugly
|
||||
var nextToken = Peek();
|
||||
if (nextToken is { Value: IdentifierToken })
|
||||
{
|
||||
var expression = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseParen);
|
||||
return expression;
|
||||
}
|
||||
case Symbol.New:
|
||||
{
|
||||
var type = ParseType();
|
||||
Dictionary<string, ExpressionNode> initializers = [];
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
var startIndex = _index;
|
||||
var identifierToken = ExpectIdentifier();
|
||||
var type = NubType.Parse(identifierToken.Value);
|
||||
|
||||
if (TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
var name = ExpectIdentifier().Value;
|
||||
ExpectSymbol(Symbol.Assign);
|
||||
var value = ParseExpression();
|
||||
initializers.Add(name, value);
|
||||
var expressionToCast = ParsePrimaryExpression();
|
||||
return new CastNode(type, expressionToCast);
|
||||
}
|
||||
|
||||
return new StructInitializerNode(type, initializers);
|
||||
_index = startIndex;
|
||||
}
|
||||
default:
|
||||
|
||||
var expression = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseParen);
|
||||
return expression;
|
||||
}
|
||||
case Symbol.New:
|
||||
{
|
||||
var type = ParseType();
|
||||
Dictionary<string, ExpressionNode> initializers = [];
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
{
|
||||
throw new Exception($"Unknown symbol: {symbolToken.Symbol}");
|
||||
var name = ExpectIdentifier().Value;
|
||||
ExpectSymbol(Symbol.Assign);
|
||||
var value = ParseExpression();
|
||||
initializers.Add(name, value);
|
||||
}
|
||||
|
||||
return new StructInitializerNode(type, initializers);
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new Exception($"Unknown symbol: {symbolToken.Symbol}");
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Exception($"Unexpected token type {token.GetType().Name}");
|
||||
}
|
||||
default:
|
||||
throw new Exception($"Unexpected token type {token.GetType().Name}");
|
||||
}
|
||||
}
|
||||
|
||||
private ExpressionNode ParseExpressionIdentifier(IdentifierToken identifier)
|
||||
{
|
||||
|
||||
@@ -245,7 +245,6 @@ public class TypeChecker
|
||||
case LiteralNode literal:
|
||||
resultType = literal.LiteralType;
|
||||
break;
|
||||
|
||||
case IdentifierNode identifier:
|
||||
if (!_variables.TryGetValue(identifier.Identifier, out var varType))
|
||||
{
|
||||
@@ -253,23 +252,21 @@ public class TypeChecker
|
||||
}
|
||||
resultType = varType;
|
||||
break;
|
||||
|
||||
case BinaryExpressionNode binaryExpr:
|
||||
resultType = TypeCheckBinaryExpression(binaryExpr);
|
||||
break;
|
||||
|
||||
case CastNode cast:
|
||||
resultType = TypeCheckCast(cast);
|
||||
break;
|
||||
case FuncCallExpressionNode funcCallExpr:
|
||||
resultType = TypeCheckFuncCall(funcCallExpr.FuncCall);
|
||||
break;
|
||||
|
||||
case StructInitializerNode structInit:
|
||||
resultType = TypeCheckStructInitializer(structInit);
|
||||
break;
|
||||
|
||||
case StructFieldAccessorNode fieldAccess:
|
||||
resultType = TypeCheckStructFieldAccess(fieldAccess);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new TypeCheckingException($"Unsupported expression type: {expression.GetType().Name}");
|
||||
}
|
||||
@@ -316,6 +313,13 @@ public class TypeChecker
|
||||
}
|
||||
}
|
||||
|
||||
private NubType TypeCheckCast(CastNode cast)
|
||||
{
|
||||
TypeCheckExpression(cast.Expression);
|
||||
// TODO: Check if castable
|
||||
return cast.TargetType;
|
||||
}
|
||||
|
||||
private NubType TypeCheckStructInitializer(StructInitializerNode structInit)
|
||||
{
|
||||
var structType = structInit.StructType;
|
||||
|
||||
Reference in New Issue
Block a user