WIP: dev #1
@@ -301,13 +301,13 @@ public class Generator
|
|||||||
{
|
{
|
||||||
foreach (var @case in statement.Cases)
|
foreach (var @case in statement.Cases)
|
||||||
{
|
{
|
||||||
var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == @case.Type.Ident);
|
var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == @case.Variant.Ident);
|
||||||
|
|
||||||
writer.WriteLine($"case {tag}:");
|
writer.WriteLine($"case {tag}:");
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
using (writer.Indent())
|
using (writer.Indent())
|
||||||
{
|
{
|
||||||
writer.WriteLine($"auto {@case.VariableName.Ident} = {target}.{@case.Type.Ident};");
|
writer.WriteLine($"auto {@case.VariableName.Ident} = {target}.{@case.Variant.Ident};");
|
||||||
EmitStatement(@case.Body);
|
EmitStatement(@case.Body);
|
||||||
}
|
}
|
||||||
writer.WriteLine("}");
|
writer.WriteLine("}");
|
||||||
|
|||||||
@@ -191,9 +191,22 @@ public class TypeChecker
|
|||||||
if (target.Type is not NubTypeEnum enumType)
|
if (target.Type is not NubTypeEnum enumType)
|
||||||
throw BasicError("A match statement can only be used on enum types", target);
|
throw BasicError("A match statement can only be used on enum types", target);
|
||||||
|
|
||||||
|
if (!moduleGraph.TryResolveType(enumType.Module, enumType.Name, enumType.Module == currentModule, out var info))
|
||||||
|
throw BasicError($"Type '{enumType}' not found", target);
|
||||||
|
|
||||||
|
if (info is not Module.TypeInfoEnum enumInfo)
|
||||||
|
throw BasicError($"Type '{enumType}' is not an enum", target);
|
||||||
|
|
||||||
|
var uncoveredCases = enumInfo.Variants.Select(x => x.Name).ToList();
|
||||||
|
|
||||||
var cases = new List<TypedNodeStatementMatch.Case>();
|
var cases = new List<TypedNodeStatementMatch.Case>();
|
||||||
foreach (var @case in statement.Cases)
|
foreach (var @case in statement.Cases)
|
||||||
{
|
{
|
||||||
|
if (!enumInfo.Variants.Any(x => x.Name == @case.Variant.Ident))
|
||||||
|
throw BasicError($"Enum type'{enumType}' does not have a variant named '{@case.Variant.Ident}'", @case.Variant);
|
||||||
|
|
||||||
|
uncoveredCases.Remove(@case.Variant.Ident);
|
||||||
|
|
||||||
using (scope.EnterScope())
|
using (scope.EnterScope())
|
||||||
{
|
{
|
||||||
scope.DeclareIdentifier(@case.VariableName.Ident, NubTypeEnumVariant.Get(NubTypeEnum.Get(enumType.Module, enumType.Name), @case.Variant.Ident));
|
scope.DeclareIdentifier(@case.VariableName.Ident, NubTypeEnumVariant.Get(NubTypeEnum.Get(enumType.Module, enumType.Name), @case.Variant.Ident));
|
||||||
@@ -202,6 +215,9 @@ public class TypeChecker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uncoveredCases.Any())
|
||||||
|
throw BasicError($"Match statement does not cover the following cases: {string.Join(", ", uncoveredCases)}", statement);
|
||||||
|
|
||||||
return new TypedNodeStatementMatch(statement.Tokens, target, cases);
|
return new TypedNodeStatementMatch(statement.Tokens, target, cases);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,7 +807,7 @@ public class TypedNodeStatementMatch(List<Token> tokens, TypedNodeExpression tar
|
|||||||
|
|
||||||
public class Case(List<Token> tokens, TokenIdent type, TokenIdent variableName, TypedNodeStatement body) : Node(tokens)
|
public class Case(List<Token> tokens, TokenIdent type, TokenIdent variableName, TypedNodeStatement body) : Node(tokens)
|
||||||
{
|
{
|
||||||
public TokenIdent Type { get; } = type;
|
public TokenIdent Variant { get; } = type;
|
||||||
public TokenIdent VariableName { get; } = variableName;
|
public TokenIdent VariableName { get; } = variableName;
|
||||||
public TypedNodeStatement Body { get; } = body;
|
public TypedNodeStatement Body { get; } = body;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,34 @@
|
|||||||
module math
|
module math
|
||||||
|
|
||||||
export struct vec2 {
|
export struct Human {
|
||||||
|
name: string
|
||||||
|
age: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
export struct Pos {
|
||||||
x: i32
|
x: i32
|
||||||
y: i32
|
y: i32
|
||||||
}
|
}
|
||||||
|
|
||||||
export struct vec3 {
|
export enum Message {
|
||||||
x: i32
|
Quit: {}
|
||||||
y: i32
|
Move: Pos
|
||||||
z: i32
|
|
||||||
}
|
|
||||||
|
|
||||||
export struct color {
|
|
||||||
r: i32
|
|
||||||
g: i32
|
|
||||||
b: i32
|
|
||||||
a: i32
|
|
||||||
}
|
|
||||||
|
|
||||||
export struct example {
|
|
||||||
b: color
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum message {
|
|
||||||
quit: {}
|
|
||||||
move: color
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export func add(a: i32 b: i32): i32
|
export func add(a: i32 b: i32): i32
|
||||||
{
|
{
|
||||||
let message: message = enum message::move {
|
let msg: Message = enum Message::Move {
|
||||||
r = 23
|
x = 10
|
||||||
g = 46
|
y = 10
|
||||||
b = 56
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match message {
|
match msg {
|
||||||
quit q {}
|
Quit q {
|
||||||
move m {
|
// quit
|
||||||
m.r = 23
|
}
|
||||||
m.g = 23
|
Move m {
|
||||||
m.b = 23
|
// move
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let color: color = {
|
|
||||||
r = 23
|
|
||||||
g = 23
|
|
||||||
b = 23
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return add_internal(a b)
|
return add_internal(a b)
|
||||||
|
|||||||
Reference in New Issue
Block a user