...
This commit is contained in:
@@ -119,20 +119,9 @@ public class TypeChecker
|
|||||||
if (statement.Expression is not NodeExpressionFuncCall funcCall)
|
if (statement.Expression is not NodeExpressionFuncCall funcCall)
|
||||||
throw BasicError("Expected statement or function call", statement);
|
throw BasicError("Expected statement or function call", statement);
|
||||||
|
|
||||||
var target = CheckExpression(funcCall.Target, null);
|
var expr = CheckExpressionFuncCall(funcCall, null);
|
||||||
if (target.Type is not NubTypeFunc funcType)
|
|
||||||
throw BasicError("Expected a function type", target);
|
|
||||||
|
|
||||||
if (funcType.Parameters.Count != funcCall.Parameters.Count)
|
return new TypedNodeStatementFuncCall(expr.Tokens, expr.Target, expr.Parameters);
|
||||||
throw BasicError($"Expected {funcType.Parameters.Count} parameters but got {funcCall.Parameters.Count}", funcCall);
|
|
||||||
|
|
||||||
var parameters = new List<TypedNodeExpression>();
|
|
||||||
for (int i = 0; i < funcCall.Parameters.Count; i++)
|
|
||||||
{
|
|
||||||
parameters.Add(CheckExpression(funcCall.Parameters[i], funcType.Parameters[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TypedNodeStatementFuncCall(statement.Tokens, target, parameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypedNodeStatementIf CheckStatementIf(NodeStatementIf statement)
|
private TypedNodeStatementIf CheckStatementIf(NodeStatementIf statement)
|
||||||
@@ -432,6 +421,14 @@ public class TypeChecker
|
|||||||
|
|
||||||
return new TypedNodeExpressionMemberAccess(expression.Tokens, field.Type, target, expression.Name);
|
return new TypedNodeExpressionMemberAccess(expression.Tokens, field.Type, target, expression.Name);
|
||||||
}
|
}
|
||||||
|
case NubTypeAnonymousStruct anonymousStructType:
|
||||||
|
{
|
||||||
|
var field = anonymousStructType.Fields.FirstOrDefault(x => x.Name == expression.Name.Ident);
|
||||||
|
if (field == null)
|
||||||
|
throw BasicError($"Struct '{target.Type}' does not have a field matching the name '{expression.Name.Ident}'", target);
|
||||||
|
|
||||||
|
return new TypedNodeExpressionMemberAccess(expression.Tokens, field.Type, target, expression.Name);
|
||||||
|
}
|
||||||
case NubTypeEnumVariant enumVariantType:
|
case NubTypeEnumVariant enumVariantType:
|
||||||
{
|
{
|
||||||
if (!moduleGraph.TryResolveModule(enumVariantType.EnumType.Module, out var module))
|
if (!moduleGraph.TryResolveModule(enumVariantType.EnumType.Module, out var module))
|
||||||
@@ -466,7 +463,11 @@ public class TypeChecker
|
|||||||
var parameters = new List<TypedNodeExpression>();
|
var parameters = new List<TypedNodeExpression>();
|
||||||
for (int i = 0; i < expression.Parameters.Count; i++)
|
for (int i = 0; i < expression.Parameters.Count; i++)
|
||||||
{
|
{
|
||||||
parameters.Add(CheckExpression(expression.Parameters[i], funcType.Parameters[i]));
|
var parameter = CheckExpression(expression.Parameters[i], funcType.Parameters[i]);
|
||||||
|
if (!parameter.Type.IsAssignableTo(funcType.Parameters[i]))
|
||||||
|
throw BasicError($"Parameter {i + 1} does is not assignable to '{funcType.Parameters[i]}'", parameter);
|
||||||
|
|
||||||
|
parameters.Add(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TypedNodeExpressionFuncCall(expression.Tokens, funcType.ReturnType, target, parameters);
|
return new TypedNodeExpressionFuncCall(expression.Tokens, funcType.ReturnType, target, parameters);
|
||||||
@@ -484,7 +485,7 @@ public class TypeChecker
|
|||||||
var type = ResolveType(expression.Type);
|
var type = ResolveType(expression.Type);
|
||||||
if (type is not NubTypeStruct structType)
|
if (type is not NubTypeStruct structType)
|
||||||
throw BasicError("Type of struct literal is not a struct", expression);
|
throw BasicError("Type of struct literal is not a struct", expression);
|
||||||
|
|
||||||
if (!moduleGraph.TryResolveType(structType.Module, structType.Name, structType.Module == currentModule, out var info))
|
if (!moduleGraph.TryResolveType(structType.Module, structType.Name, structType.Module == currentModule, out var info))
|
||||||
throw BasicError($"Type '{structType}' struct literal not found", expression);
|
throw BasicError($"Type '{structType}' struct literal not found", expression);
|
||||||
|
|
||||||
@@ -531,7 +532,24 @@ public class TypeChecker
|
|||||||
|
|
||||||
return new TypedNodeExpressionStructLiteral(expression.Tokens, structType, initializers);
|
return new TypedNodeExpressionStructLiteral(expression.Tokens, structType, initializers);
|
||||||
}
|
}
|
||||||
// todo(nub31): Infer anonymous struct types if expectedType is anonymous struct
|
else if (expectedType is NubTypeAnonymousStruct anonymousStructType)
|
||||||
|
{
|
||||||
|
var initializers = new List<TypedNodeExpressionStructLiteral.Initializer>();
|
||||||
|
foreach (var initializer in expression.Initializers)
|
||||||
|
{
|
||||||
|
var field = anonymousStructType.Fields.FirstOrDefault(x => x.Name == initializer.Name.Ident);
|
||||||
|
if (field == null)
|
||||||
|
throw BasicError($"Field '{initializer.Name.Ident}' does not exist on anonymous struct '{anonymousStructType}'", initializer.Name);
|
||||||
|
|
||||||
|
var value = CheckExpression(initializer.Value, field.Type);
|
||||||
|
if (!value.Type.IsAssignableTo(field.Type))
|
||||||
|
throw BasicError($"Type of assignment ({value.Type}) does not match expected type of field '{field.Name}' ({field.Type})", initializer.Name);
|
||||||
|
|
||||||
|
initializers.Add(new TypedNodeExpressionStructLiteral.Initializer(initializer.Tokens, initializer.Name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TypedNodeExpressionStructLiteral(expression.Tokens, anonymousStructType, initializers);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var initializers = new List<TypedNodeExpressionStructLiteral.Initializer>();
|
var initializers = new List<TypedNodeExpressionStructLiteral.Initializer>();
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
pushd core
|
||||||
|
dotnet run --project ../../compiler print.nub --type=lib
|
||||||
|
popd
|
||||||
|
|
||||||
pushd math
|
pushd math
|
||||||
dotnet run --project ../../compiler math.nub --type=lib
|
dotnet run --project ../../compiler math.nub --type=lib
|
||||||
# pushd .build
|
|
||||||
# unzip out.nublib
|
|
||||||
# popd
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd program
|
pushd program
|
||||||
dotnet run --project ../../compiler main.nub ../math/.build/out.nublib
|
dotnet run --project ../../compiler main.nub ../math/.build/out.nublib ../core/.build/out.nublib
|
||||||
popd
|
popd
|
||||||
6
examples/core/print.nub
Normal file
6
examples/core/print.nub
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module print
|
||||||
|
|
||||||
|
extern func puts(^u8 text)
|
||||||
|
|
||||||
|
export func print(text: string) {
|
||||||
|
}
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
|
struct Pos {
|
||||||
|
x: i32
|
||||||
|
y: i32
|
||||||
|
}
|
||||||
|
|
||||||
func main(): i32
|
func main(): i32
|
||||||
{
|
{
|
||||||
return math::add(1 2)
|
test({ x = 23 y = 23 })
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func test(x: Pos): void
|
||||||
|
{
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user