From 2b7eb56895a6d7194c64d74ccc705515186211a7 Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 1 Mar 2026 18:14:54 +0100 Subject: [PATCH] ... --- TODO.txt | 1 - compiler/Generator.cs | 96 ++++++++++++++++++++++------------ compiler/ModuleGraph.cs | 6 +-- compiler/NubLib.cs | 2 +- compiler/Parser.cs | 105 ++++++++++++++++++++------------------ compiler/Tokenizer.cs | 3 ++ compiler/TypeChecker.cs | 89 +++++++++++++++----------------- examples/core/sys.nub | 6 +-- examples/program/main.nub | 22 ++++++++ 9 files changed, 192 insertions(+), 138 deletions(-) diff --git a/TODO.txt b/TODO.txt index 180dc83..ecf8716 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,4 +1,3 @@ -Comma seperated function parameters and struct/enum mebers Converting ^u8 to string string formatting Dynamic arrays diff --git a/compiler/Generator.cs b/compiler/Generator.cs index a2ebf17..9e95965 100644 --- a/compiler/Generator.cs +++ b/compiler/Generator.cs @@ -1,5 +1,7 @@ using System.Diagnostics; +using System.Security.Principal; using System.Text; +using Microsoft.VisualBasic; namespace Compiler; @@ -260,7 +262,12 @@ public class Generator throw new UnreachableException(); foreach (var variant in enumInfo.Variants) - EmitTypeDefinitionIfNotEmitted(variant.Type); + { + if (variant.Type is not null) + { + EmitTypeDefinitionIfNotEmitted(variant.Type); + } + } writer.WriteLine($"struct {NameMangler.Mangle(enumType.Module, enumType.Name, enumType)}"); writer.WriteLine("{"); @@ -273,7 +280,10 @@ public class Generator { foreach (var variant in enumInfo.Variants) { - writer.WriteLine($"{CType(variant.Type, variant.Name)};"); + if (variant.Type is not null) + { + writer.WriteLine($"{CType(variant.Type, variant.Name)};"); + } } } writer.WriteLine("};"); @@ -453,7 +463,12 @@ public class Generator using (writer.Indent()) { PushScope(); - writer.WriteLine($"{CType(variantInfo.Type, @case.VariableName.Ident)} = {target}.{@case.Variant.Ident};"); + if (@case.VariableName != null) + { + Debug.Assert(variantInfo.Type is not null); + writer.WriteLine($"{CType(variantInfo.Type, @case.VariableName.Ident)} = {target}.{@case.Variant.Ident};"); + } + EmitStatement(@case.Body); PopScope(); writer.WriteLine("break;"); @@ -474,7 +489,7 @@ public class Generator TypedNodeExpressionIntLiteral expression => expression.Value.Value.ToString(), TypedNodeExpressionStringLiteral expression => EmitExpressionStringLiteral(expression), TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression), - TypedNodeExpressionEnumLiteral expression => EmitExpressionEnumLiteral(expression), + TypedNodeExpressionNewNamedType expression => EmitNodeExpressionNewNamedType(expression), TypedNodeExpressionStructMemberAccess expression => EmitExpressionMemberAccess(expression), TypedNodeExpressionStringLength expression => EmitExpressionStringLength(expression), TypedNodeExpressionStringPointer expression => EmitExpressionStringPointer(expression), @@ -563,25 +578,35 @@ public class Generator return name; } - private string EmitExpressionEnumLiteral(TypedNodeExpressionEnumLiteral expression) + private string EmitNodeExpressionNewNamedType(TypedNodeExpressionNewNamedType expression) { - var name = TmpName(); - scopes.Peek().DeconstructableNames.Add((name, expression.Type)); + switch (expression.Type) + { + case NubTypeEnumVariant enumVariantType: + { + var name = TmpName(); + scopes.Peek().DeconstructableNames.Add((name, expression.Type)); - var enumVariantType = (NubTypeEnumVariant)expression.Type; + if (!moduleGraph.TryResolveType(enumVariantType.EnumType.Module, enumVariantType.EnumType.Name, true, out var info)) + throw new UnreachableException(); - if (!moduleGraph.TryResolveType(enumVariantType.EnumType.Module, enumVariantType.EnumType.Name, true, out var info)) - throw new UnreachableException(); + var enumInfo = (Module.TypeInfoEnum)info; + var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == enumVariantType.Variant); - var enumInfo = (Module.TypeInfoEnum)info; - var tag = enumInfo.Variants.ToList().FindIndex(x => x.Name == enumVariantType.Variant); + var value = EmitExpression(expression.Value); + EmitCopyConstructor(value, expression.Value.Type); - var value = EmitExpression(expression.Value); - EmitCopyConstructor(value, expression.Value.Type); + writer.WriteLine($"{CType(expression.Type, name)} = ({CType(expression.Type)}){{ .tag = {tag}, .{enumVariantType.Variant} = {value} }};"); - writer.WriteLine($"{CType(expression.Type, name)} = ({CType(expression.Type)}){{ .tag = {tag}, .{enumVariantType.Variant} = {value} }};"); - - return name; + return name; + } + case NubTypeStruct structType: + { + return EmitExpression(expression.Value); + } + default: + throw new UnreachableException(); + } } private string EmitExpressionMemberAccess(TypedNodeExpressionStructMemberAccess expression) @@ -710,14 +735,17 @@ public class Generator { Module.TypeInfoEnum.Variant variant = enumInfo.Variants[i]; - writer.WriteLine($"case {i}:"); - writer.WriteLine("{"); - using (writer.Indent()) + if (variant.Type is not null) { - EmitCopyConstructor($"{value}.{variant.Name}", variant.Type); - writer.WriteLine("break;"); + writer.WriteLine($"case {i}:"); + writer.WriteLine("{"); + using (writer.Indent()) + { + EmitCopyConstructor($"{value}.{variant.Name}", variant.Type); + writer.WriteLine("break;"); + } + writer.WriteLine("}"); } - writer.WriteLine("}"); } } writer.WriteLine("}"); @@ -729,8 +757,9 @@ public class Generator throw new UnreachableException(); var variant = enumInfo.Variants.First(x => x.Name == enumVariantType.Variant); + if (variant.Type is not null) + EmitCopyConstructor($"{value}.{variant.Name}", variant.Type); - EmitCopyConstructor($"{value}.{variant.Name}", variant.Type); break; } } @@ -776,15 +805,17 @@ public class Generator for (int i = 0; i < enumInfo.Variants.Count; i++) { var variant = enumInfo.Variants[i]; - - writer.WriteLine($"case {i}:"); - writer.WriteLine("{"); - using (writer.Indent()) + if (variant.Type is not null) { - EmitCopyDestructor($"{value}.{variant.Name}", variant.Type); - writer.WriteLine("break;"); + writer.WriteLine($"case {i}:"); + writer.WriteLine("{"); + using (writer.Indent()) + { + EmitCopyDestructor($"{value}.{variant.Name}", variant.Type); + writer.WriteLine("break;"); + } + writer.WriteLine("}"); } - writer.WriteLine("}"); } } writer.WriteLine("}"); @@ -796,8 +827,9 @@ public class Generator throw new UnreachableException(); var variant = enumInfo.Variants.First(x => x.Name == enumVariantType.Variant); + if (variant.Type is not null) + EmitCopyDestructor($"{value}.{variant.Name}", variant.Type); - EmitCopyDestructor($"{value}.{variant.Name}", variant.Type); break; } } diff --git a/compiler/ModuleGraph.cs b/compiler/ModuleGraph.cs index e973fbe..6d9120e 100644 --- a/compiler/ModuleGraph.cs +++ b/compiler/ModuleGraph.cs @@ -150,7 +150,7 @@ public class ModuleGraph if (typeInfo is Module.TypeInfoEnum enumType) { - var variants = enumDef.Variants.Select(v => new Module.TypeInfoEnum.Variant(v.Name.Ident, ResolveType(v.Type, module.Name))).ToList(); + var variants = enumDef.Variants.Select(v => new Module.TypeInfoEnum.Variant(v.Name.Ident, v.Type == null ? null : ResolveType(v.Type, module.Name))).ToList(); enumType.SetVariants(variants); } } @@ -435,10 +435,10 @@ public class Module(string name) this.variants = variants; } - public class Variant(string name, NubType type) + public class Variant(string name, NubType? type) { public string Name { get; } = name; - public NubType Type { get; } = type; + public NubType? Type { get; } = type; } } } \ No newline at end of file diff --git a/compiler/NubLib.cs b/compiler/NubLib.cs index a3f7fef..9ed95cc 100644 --- a/compiler/NubLib.cs +++ b/compiler/NubLib.cs @@ -104,7 +104,7 @@ public record Manifest(Dictionary Modules) public record TypeInfoEnum(bool Exported, IReadOnlyList Variants) : TypeInfo(Exported) { - public record Variant(string Name, NubType Type); + public record Variant(string Name, NubType? Type); } } } \ No newline at end of file diff --git a/compiler/Parser.cs b/compiler/Parser.cs index 7f9ba3d..2830127 100644 --- a/compiler/Parser.cs +++ b/compiler/Parser.cs @@ -86,17 +86,7 @@ public class Parser throw BasicError("Invalid modifier for function", modifier.Value); var name = ExpectIdent(); - var parameters = new List(); - - ExpectSymbol(Symbol.OpenParen); - while (!TryExpectSymbol(Symbol.CloseParen)) - { - var paramStartIndex = index; - var parameterName = ExpectIdent(); - ExpectSymbol(Symbol.Colon); - var parameterType = ParseType(); - parameters.Add(new NodeDefinitionFunc.Param(TokensFrom(paramStartIndex), parameterName, parameterType)); - } + var parameters = ParseFuncParameters(); NodeType? returnType = null; if (TryExpectSymbol(Symbol.Colon)) @@ -132,6 +122,7 @@ public class Parser var fieldName = ExpectIdent(); ExpectSymbol(Symbol.Colon); var fieldType = ParseType(); + TryExpectSymbol(Symbol.Comma); fields.Add(new NodeDefinitionStruct.Field(TokensFrom(fieldStartIndex), fieldName, fieldType)); } @@ -154,8 +145,13 @@ public class Parser { var variantsStartIndex = index; var variantName = ExpectIdent(); - ExpectSymbol(Symbol.Colon); - var variantType = ParseType(); + + NodeType? variantType = null; + if (TryExpectSymbol(Symbol.Colon)) + variantType = ParseType(); + + TryExpectSymbol(Symbol.Comma); + variants.Add(new NodeDefinitionEnum.Variant(TokensFrom(variantsStartIndex), variantName, variantType)); } @@ -180,6 +176,35 @@ public class Parser throw BasicError("Not a valid definition", Peek()); } + private List ParseFuncParameters() + { + var parameters = new List(); + + ExpectSymbol(Symbol.OpenParen); + + while (true) + { + if (TryExpectSymbol(Symbol.CloseParen)) + break; + + var startIndex = index; + + var name = ExpectIdent(); + ExpectSymbol(Symbol.Colon); + var type = ParseType(); + + parameters.Add(new NodeDefinitionFunc.Param(TokensFrom(startIndex), name, type)); + + if (!TryExpectSymbol(Symbol.Comma)) + { + ExpectSymbol(Symbol.CloseParen); + break; + } + } + + return parameters; + } + private NodeStatement ParseStatement() { var startIndex = index; @@ -251,10 +276,10 @@ public class Parser while (!TryExpectSymbol(Symbol.CloseCurly)) { var caseStartIndex = index; - var type = ExpectIdent(); - var variableName = ExpectIdent(); + var variant = ExpectIdent(); + TryExpectIdent(out var variableName); var body = ParseStatement(); - cases.Add(new NodeStatementMatch.Case(TokensFrom(caseStartIndex), type, variableName, body)); + cases.Add(new NodeStatementMatch.Case(TokensFrom(caseStartIndex), variant, variableName, body)); } return new NodeStatementMatch(TokensFrom(startIndex), target, cases); @@ -350,7 +375,7 @@ public class Parser initializers.Add(new NodeExpressionStructLiteral.Initializer(TokensFrom(initializerStartIndex), fieldName, fieldValue)); } - expr = new NodeExpressionStructLiteral(TokensFrom(startIndex), null, initializers); + expr = new NodeExpressionStructLiteral(TokensFrom(startIndex), initializers); } else if (TryExpectSymbol(Symbol.Bang)) { @@ -380,30 +405,11 @@ public class Parser expr = new NodeExpressionIdent(TokensFrom(startIndex), sections); } - else if (TryExpectKeyword(Keyword.Struct)) - { - var type = ParseType(); - - var initializers = new List(); - - ExpectSymbol(Symbol.OpenCurly); - while (!TryExpectSymbol(Symbol.CloseCurly)) - { - var initializerStartIndex = startIndex; - var fieldName = ExpectIdent(); - ExpectSymbol(Symbol.Equal); - var fieldValue = ParseExpression(); - initializers.Add(new NodeExpressionStructLiteral.Initializer(TokensFrom(initializerStartIndex), fieldName, fieldValue)); - } - - expr = new NodeExpressionStructLiteral(TokensFrom(startIndex), type, initializers); - } - else if (TryExpectKeyword(Keyword.Enum)) + else if (TryExpectKeyword(Keyword.New)) { var type = ParseType(); var value = ParseExpression(); - - expr = new NodeExpressionEnumLiteral(TokensFrom(startIndex), type, value); + return new NodeExpressionNewNamedType(TokensFrom(startIndex), type, value); } else { @@ -769,10 +775,10 @@ public class NodeDefinitionEnum(List tokens, bool exported, TokenIdent na public TokenIdent Name { get; } = name; public List Variants { get; } = variants; - public class Variant(List tokens, TokenIdent name, NodeType type) : Node(tokens) + public class Variant(List tokens, TokenIdent name, NodeType? type) : Node(tokens) { public TokenIdent Name { get; } = name; - public NodeType Type { get; } = type; + public NodeType? Type { get; } = type; } } @@ -838,10 +844,10 @@ public class NodeStatementMatch(List tokens, NodeExpression target, List< public NodeExpression Target { get; } = target; public List Cases { get; } = cases; - public class Case(List tokens, TokenIdent type, TokenIdent variableName, NodeStatement body) : Node(tokens) + public class Case(List tokens, TokenIdent type, TokenIdent? variableName, NodeStatement body) : Node(tokens) { public TokenIdent Variant { get; } = type; - public TokenIdent VariableName { get; } = variableName; + public TokenIdent? VariableName { get; } = variableName; public NodeStatement Body { get; } = body; } } @@ -863,9 +869,14 @@ public class NodeExpressionBoolLiteral(List tokens, TokenBoolLiteral valu public TokenBoolLiteral Value { get; } = value; } -public class NodeExpressionStructLiteral(List tokens, NodeType? type, List initializers) : NodeExpression(tokens) +public class NodeExpressionNewNamedType(List tokens, NodeType type, NodeExpression value) : NodeExpression(tokens) +{ + public NodeType Type { get; } = type; + public NodeExpression Value { get; } = value; +} + +public class NodeExpressionStructLiteral(List tokens, List initializers) : NodeExpression(tokens) { - public NodeType? Type { get; } = type; public List Initializers { get; } = initializers; public class Initializer(List tokens, TokenIdent name, NodeExpression value) : Node(tokens) @@ -875,12 +886,6 @@ public class NodeExpressionStructLiteral(List tokens, NodeType? type, Lis } } -public class NodeExpressionEnumLiteral(List tokens, NodeType type, NodeExpression value) : NodeExpression(tokens) -{ - public NodeType Type { get; } = type; - public NodeExpression Value { get; } = value; -} - public class NodeExpressionMemberAccess(List tokens, NodeExpression target, TokenIdent name) : NodeExpression(tokens) { public NodeExpression Target { get; } = target; diff --git a/compiler/Tokenizer.cs b/compiler/Tokenizer.cs index a928db2..a340f28 100644 --- a/compiler/Tokenizer.cs +++ b/compiler/Tokenizer.cs @@ -389,6 +389,7 @@ public class Tokenizer "struct" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Struct), "packed" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Packed), "enum" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Enum), + "new" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.New), "match" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Match), "let" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Let), "if" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.If), @@ -538,6 +539,7 @@ public enum Keyword Struct, Packed, Enum, + New, Match, Let, If, @@ -605,6 +607,7 @@ public static class TokenExtensions Keyword.Struct => "struct", Keyword.Packed => "packed", Keyword.Enum => "enum", + Keyword.New => "new", Keyword.Match => "enum", Keyword.Let => "let", Keyword.If => "if", diff --git a/compiler/TypeChecker.cs b/compiler/TypeChecker.cs index dfd8bf3..3fbf68b 100644 --- a/compiler/TypeChecker.cs +++ b/compiler/TypeChecker.cs @@ -208,15 +208,24 @@ public class TypeChecker var cases = new List(); foreach (var @case in statement.Cases) { - if (!enumInfo.Variants.Any(x => x.Name == @case.Variant.Ident)) + var variant = enumInfo.Variants.FirstOrDefault(x => x.Name == @case.Variant.Ident); + if (variant == null) throw BasicError($"Enum type'{enumType}' does not have a variant named '{@case.Variant.Ident}'", @case.Variant); uncoveredCases.Remove(@case.Variant.Ident); using (scope.EnterScope()) { - scope.DeclareIdentifier(@case.VariableName.Ident, NubTypeEnumVariant.Get(NubTypeEnum.Get(enumType.Module, enumType.Name), @case.Variant.Ident)); + if (@case.VariableName != null) + { + if (variant.Type is null) + throw BasicError("Cannot capture variable for enum variant without type", @case.VariableName); + + scope.DeclareIdentifier(@case.VariableName.Ident, variant.Type); + } + var body = CheckStatement(@case.Body); + cases.Add(new TypedNodeStatementMatch.Case(@case.Tokens, @case.Variant, @case.VariableName, body)); } } @@ -240,7 +249,7 @@ public class TypeChecker NodeExpressionFuncCall expression => CheckExpressionFuncCall(expression, expectedType), NodeExpressionStringLiteral expression => CheckExpressionStringLiteral(expression, expectedType), NodeExpressionStructLiteral expression => CheckExpressionStructLiteral(expression, expectedType), - NodeExpressionEnumLiteral expression => CheckExpressionEnumLiteral(expression, expectedType), + NodeExpressionNewNamedType expression => CheckExpressionNewNamedType(expression, expectedType), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; } @@ -517,35 +526,7 @@ public class TypeChecker private TypedNodeExpressionStructLiteral CheckExpressionStructLiteral(NodeExpressionStructLiteral expression, NubType? expectedType) { - if (expression.Type != null) - { - var type = ResolveType(expression.Type); - if (type is not NubTypeStruct structType) - throw BasicError("Type of struct literal is not a struct", expression); - - if (!moduleGraph.TryResolveType(structType.Module, structType.Name, structType.Module == currentModule, out var info)) - throw BasicError($"Type '{structType}' struct literal not found", expression); - - if (info is not Module.TypeInfoStruct structInfo) - throw BasicError($"Type '{structType}' is not a struct", expression.Type); - - var initializers = new List(); - foreach (var initializer in expression.Initializers) - { - var field = structInfo.Fields.FirstOrDefault(x => x.Name == initializer.Name.Ident); - if (field == null) - throw BasicError($"Field '{initializer.Name.Ident}' does not exist on struct '{structType.Module}::{structType.Name}'", 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, structType, initializers); - } - else if (expectedType is NubTypeStruct structType) + if (expectedType is NubTypeStruct structType) { if (!moduleGraph.TryResolveType(structType.Module, structType.Name, structType.Module == currentModule, out var info)) throw BasicError($"Type '{structType}' struct literal not found", expression); @@ -602,24 +583,36 @@ public class TypeChecker } } - private TypedNodeExpressionEnumLiteral CheckExpressionEnumLiteral(NodeExpressionEnumLiteral expression, NubType? expectedType) + private TypedNodeExpressionNewNamedType CheckExpressionNewNamedType(NodeExpressionNewNamedType expression, NubType? expectedType) { var type = ResolveType(expression.Type); - if (type is not NubTypeEnumVariant variantType) - throw BasicError("Expected enum variant type", expression.Type); + switch (type) + { + case NubTypeStruct structType: + { + var value = CheckExpression(expression.Value, structType); + return new TypedNodeExpressionNewNamedType(expression.Tokens, structType, value); + } + case NubTypeEnumVariant enumVariantType: + { + if (!moduleGraph.TryResolveType(enumVariantType.EnumType.Module, enumVariantType.EnumType.Name, enumVariantType.EnumType.Module == currentModule, out var info)) + throw BasicError($"Type '{enumVariantType.EnumType}' not found", expression.Type); - if (!moduleGraph.TryResolveType(variantType.EnumType.Module, variantType.EnumType.Name, variantType.EnumType.Module == currentModule, out var info)) - throw BasicError($"Type '{variantType.EnumType}' not found", expression.Type); + if (info is not Module.TypeInfoEnum enumInfo) + throw BasicError($"Type '{enumVariantType.EnumType}' is not an enum", expression.Type); - if (info is not Module.TypeInfoEnum enumInfo) - throw BasicError($"Type '{variantType.EnumType}' is not an enum", expression.Type); + var variant = enumInfo.Variants.FirstOrDefault(x => x.Name == enumVariantType.Variant); + if (variant == null) + throw BasicError($"Enum type '{enumVariantType.EnumType}' does not have a variant named '{enumVariantType.Variant}'", expression.Type); - var variant = enumInfo.Variants.FirstOrDefault(x => x.Name == variantType.Variant); - if (variant == null) - throw BasicError($"Enum '{variantType.EnumType}' does not have a variant named '{variantType.Variant}'", expression.Type); - - var value = CheckExpression(expression.Value, variant.Type); - return new TypedNodeExpressionEnumLiteral(expression.Tokens, type, value); + var value = CheckExpression(expression.Value, variant.Type); + return new TypedNodeExpressionNewNamedType(expression.Tokens, enumVariantType, value); + } + default: + { + throw BasicError($"'{type}' is not a valid type for the new operator", expression); + } + } } private NubType ResolveType(NodeType node) @@ -860,10 +853,10 @@ public class TypedNodeStatementMatch(List tokens, TypedNodeExpression tar public TypedNodeExpression Target { get; } = target; public List Cases { get; } = cases; - public class Case(List tokens, TokenIdent type, TokenIdent variableName, TypedNodeStatement body) : Node(tokens) + public class Case(List tokens, TokenIdent type, TokenIdent? variableName, TypedNodeStatement body) : Node(tokens) { public TokenIdent Variant { get; } = type; - public TokenIdent VariableName { get; } = variableName; + public TokenIdent? VariableName { get; } = variableName; public TypedNodeStatement Body { get; } = body; } } @@ -899,7 +892,7 @@ public class TypedNodeExpressionStructLiteral(List tokens, NubType type, } } -public class TypedNodeExpressionEnumLiteral(List tokens, NubType type, TypedNodeExpression value) : TypedNodeExpression(tokens, type) +public class TypedNodeExpressionNewNamedType(List tokens, NubType type, TypedNodeExpression value) : TypedNodeExpression(tokens, type) { public TypedNodeExpression Value { get; } = value; } diff --git a/examples/core/sys.nub b/examples/core/sys.nub index d9a894f..1ca9d13 100644 --- a/examples/core/sys.nub +++ b/examples/core/sys.nub @@ -1,5 +1,5 @@ module sys -export extern func read(fd: u32 buf: ^u8 count: u64): i64 -export extern func write(fd: u32 buf: ^u8 count: u64): i64 -export extern func open(fileName: ^u8 flags: i32 mode: u16): i64 \ No newline at end of file +export extern func read(fd: u32, buf: ^u8, count: u64): i64 +export extern func write(fd: u32, buf: ^u8, count: u64): i64 +export extern func open(fileName: ^u8, flags: i32, mode: u16): i64 \ No newline at end of file diff --git a/examples/program/main.nub b/examples/program/main.nub index 2e80c54..d9b8b1e 100644 --- a/examples/program/main.nub +++ b/examples/program/main.nub @@ -1,7 +1,29 @@ module main +struct Human { + name: string + age: i32 +} + +enum Message { + Quit + Say: string +} + func main(): i32 { core::println("Hello, world!") core::println("Hello" + "World") + + let message: Message = new Message::Say "test" + + match message { + Quit { + core::println("quit") + } + Say message { + core::println(message) + } + } + return 0 } \ No newline at end of file