...
This commit is contained in:
@@ -45,6 +45,10 @@ def map_type(clang_type: Type):
|
||||
size = canonical.get_array_size()
|
||||
return f"[{size}]{map_type(element_type)}"
|
||||
|
||||
if kind == TypeKind.INCOMPLETEARRAY:
|
||||
element_type = canonical.get_array_element_type()
|
||||
return f"[?]{map_type(element_type)}"
|
||||
|
||||
if kind == TypeKind.FUNCTIONPROTO or kind == TypeKind.FUNCTIONNOPROTO:
|
||||
arg_types = []
|
||||
|
||||
|
||||
@@ -103,10 +103,11 @@ if (modules.TryGetValue("main", out var mainModule))
|
||||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
mov rdi, rsp # Pass stack pointer to main (length + cstring pointers)
|
||||
mov rdi, [rsp] # argc
|
||||
mov rsi, [rsp + 8] # argv
|
||||
call {mainFunction.Prototype.ExternSymbol}
|
||||
mov rdi, rax # Move return value into rdi
|
||||
mov rax, 60 # syscall: exit
|
||||
mov rdi, rax # Move return value into rdi
|
||||
mov rax, 60 # syscall: exit
|
||||
syscall
|
||||
|
||||
""";
|
||||
|
||||
@@ -108,8 +108,14 @@ public record FuncIdentifierNode(List<Token> Tokens, NubType Type, string Module
|
||||
|
||||
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record ConstArrayInitializerNode(List<Token> Tokens, NubType Type, long Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record ArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record ConstArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record SliceIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record AddressOfNode(List<Token> Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record StructFieldAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
@@ -5,9 +5,6 @@ namespace NubLang.Ast;
|
||||
|
||||
public abstract class NubType : IEquatable<NubType>
|
||||
{
|
||||
public abstract bool IsValueType { get; }
|
||||
public abstract bool IsScalar { get; }
|
||||
|
||||
public override bool Equals(object? obj) => obj is NubType other && Equals(other);
|
||||
public abstract bool Equals(NubType? other);
|
||||
|
||||
@@ -20,9 +17,6 @@ public abstract class NubType : IEquatable<NubType>
|
||||
|
||||
public class NubVoidType : NubType
|
||||
{
|
||||
public override bool IsValueType => false;
|
||||
public override bool IsScalar => false;
|
||||
|
||||
public override string ToString() => "void";
|
||||
public override bool Equals(NubType? other) => other is NubVoidType;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubVoidType));
|
||||
@@ -30,9 +24,6 @@ public class NubVoidType : NubType
|
||||
|
||||
public sealed class NubIntType(bool signed, int width) : NubType
|
||||
{
|
||||
public override bool IsValueType => true;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public bool Signed { get; } = signed;
|
||||
public int Width { get; } = width;
|
||||
|
||||
@@ -43,9 +34,6 @@ public sealed class NubIntType(bool signed, int width) : NubType
|
||||
|
||||
public sealed class NubFloatType(int width) : NubType
|
||||
{
|
||||
public override bool IsValueType => true;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public int Width { get; } = width;
|
||||
|
||||
public override string ToString() => $"f{Width}";
|
||||
@@ -55,9 +43,6 @@ public sealed class NubFloatType(int width) : NubType
|
||||
|
||||
public class NubBoolType : NubType
|
||||
{
|
||||
public override bool IsValueType => true;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public override string ToString() => "bool";
|
||||
public override bool Equals(NubType? other) => other is NubBoolType;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubBoolType));
|
||||
@@ -65,9 +50,6 @@ public class NubBoolType : NubType
|
||||
|
||||
public sealed class NubPointerType(NubType baseType) : NubType
|
||||
{
|
||||
public override bool IsValueType => true;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public NubType BaseType { get; } = baseType;
|
||||
|
||||
public override string ToString() => "^" + BaseType;
|
||||
@@ -77,9 +59,6 @@ public sealed class NubPointerType(NubType baseType) : NubType
|
||||
|
||||
public class NubFuncType(List<NubType> parameters, NubType returnType) : NubType
|
||||
{
|
||||
public override bool IsValueType => true;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public List<NubType> Parameters { get; } = parameters;
|
||||
public NubType ReturnType { get; } = returnType;
|
||||
|
||||
@@ -102,9 +81,6 @@ public class NubFuncType(List<NubType> parameters, NubType returnType) : NubType
|
||||
|
||||
public class NubStructType(string module, string name, List<NubStructFieldType> fields) : NubType
|
||||
{
|
||||
public override bool IsValueType => true;
|
||||
public override bool IsScalar => false;
|
||||
|
||||
public string Module { get; } = module;
|
||||
public string Name { get; } = name;
|
||||
public List<NubStructFieldType> Fields { get; set; } = fields;
|
||||
@@ -121,43 +97,36 @@ public class NubStructFieldType(string name, NubType type, bool hasDefaultValue)
|
||||
public bool HasDefaultValue { get; } = hasDefaultValue;
|
||||
}
|
||||
|
||||
public class NubStructFuncType(string name, List<NubType> parameters, NubType returnType)
|
||||
public class NubSliceType(NubType elementType) : NubType
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
public List<NubType> Parameters { get; } = parameters;
|
||||
public NubType ReturnType { get; } = returnType;
|
||||
}
|
||||
|
||||
public class NubArrayType(NubType elementType) : NubType
|
||||
{
|
||||
public override bool IsValueType => false;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public NubType ElementType { get; } = elementType;
|
||||
|
||||
public override string ToString() => "[]" + ElementType;
|
||||
public override bool Equals(NubType? other) => other is NubArrayType array && ElementType.Equals(array.ElementType);
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubArrayType), ElementType);
|
||||
public override bool Equals(NubType? other) => other is NubSliceType slice && ElementType.Equals(slice.ElementType);
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubSliceType), ElementType);
|
||||
}
|
||||
|
||||
public class NubConstArrayType(NubType elementType, int size) : NubType
|
||||
public class NubConstArrayType(NubType elementType, long size) : NubType
|
||||
{
|
||||
public override bool IsValueType => false;
|
||||
public override bool IsScalar => true;
|
||||
|
||||
public NubType ElementType { get; } = elementType;
|
||||
public int Size { get; } = size;
|
||||
public long Size { get; } = size;
|
||||
|
||||
public override string ToString() => $"[{Size}]{ElementType}";
|
||||
public override bool Equals(NubType? other) => other is NubConstArrayType array && ElementType.Equals(array.ElementType) && Size == array.Size;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubConstArrayType), ElementType, Size);
|
||||
}
|
||||
|
||||
public class NubArrayType(NubType elementType) : NubType
|
||||
{
|
||||
public NubType ElementType { get; } = elementType;
|
||||
|
||||
public override string ToString() => $"[?]{ElementType}";
|
||||
public override bool Equals(NubType? other) => other is NubArrayType array && ElementType.Equals(array.ElementType);
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubArrayType), ElementType);
|
||||
}
|
||||
|
||||
public class NubCStringType : NubType
|
||||
{
|
||||
public override bool IsValueType => false;
|
||||
public override bool IsScalar => false;
|
||||
|
||||
public override string ToString() => "cstring";
|
||||
public override bool Equals(NubType? other) => other is NubCStringType;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubCStringType));
|
||||
@@ -165,9 +134,6 @@ public class NubCStringType : NubType
|
||||
|
||||
public class NubStringType : NubType
|
||||
{
|
||||
public override bool IsValueType => false;
|
||||
public override bool IsScalar => false;
|
||||
|
||||
public override string ToString() => "string";
|
||||
public override bool Equals(NubType? other) => other is NubStringType;
|
||||
public override int GetHashCode() => HashCode.Combine(typeof(NubStringType));
|
||||
@@ -190,7 +156,7 @@ public static class NameMangler
|
||||
NubCStringType => "CS",
|
||||
NubStringType => "S",
|
||||
NubPointerType p => "P" + EncodeType(p.BaseType),
|
||||
NubArrayType a => "A" + EncodeType(a.ElementType),
|
||||
NubSliceType a => "A" + EncodeType(a.ElementType),
|
||||
NubFuncType fn => "FN(" + string.Join(",", fn.Parameters.Select(EncodeType)) + ")" + EncodeType(fn.ReturnType),
|
||||
NubStructType st => "ST(" + st.Module + "." + st.Name + ")",
|
||||
_ => throw new NotSupportedException($"Cannot encode type: {node}")
|
||||
|
||||
@@ -248,6 +248,7 @@ public sealed class TypeChecker
|
||||
LocalIdentifierSyntax expression => CheckLocalIdentifier(expression),
|
||||
ModuleIdentifierSyntax expression => CheckModuleIdentifier(expression),
|
||||
BoolLiteralSyntax expression => CheckBoolLiteral(expression),
|
||||
ConstArrayInitializerSyntax expression => CheckConstArrayInitializer(expression),
|
||||
StringLiteralSyntax expression => CheckStringLiteral(expression, expectedType),
|
||||
IntLiteralSyntax expression => CheckIntLiteral(expression, expectedType),
|
||||
FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType),
|
||||
@@ -264,6 +265,11 @@ public sealed class TypeChecker
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result.Type is NubConstArrayType && expectedType is NubArrayType)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result.Type is NubIntType sourceIntType && expectedType is NubIntType targetIntType)
|
||||
{
|
||||
if (sourceIntType.Signed == targetIntType.Signed && sourceIntType.Width < targetIntType.Width)
|
||||
@@ -283,6 +289,13 @@ public sealed class TypeChecker
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Cannot convert {result.Type} to {expectedType}").At(node).Build());
|
||||
}
|
||||
|
||||
private ConstArrayInitializerNode CheckConstArrayInitializer(ConstArrayInitializerSyntax expression)
|
||||
{
|
||||
var elementType = ResolveType(expression.ElementType);
|
||||
var type = new NubConstArrayType(elementType, expression.Capacity);
|
||||
return new ConstArrayInitializerNode(expression.Tokens, type, expression.Capacity, elementType);
|
||||
}
|
||||
|
||||
private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression)
|
||||
{
|
||||
var value = CheckExpression(expression.Value);
|
||||
@@ -318,16 +331,18 @@ public sealed class TypeChecker
|
||||
return new AddressOfNode(expression.Tokens, type, lvalue);
|
||||
}
|
||||
|
||||
private ArrayIndexAccessNode CheckArrayIndexAccess(ArrayIndexAccessSyntax expression)
|
||||
private ExpressionNode CheckArrayIndexAccess(ArrayIndexAccessSyntax expression)
|
||||
{
|
||||
var index = CheckExpression(expression.Index, new NubIntType(false, 64));
|
||||
var target = CheckExpression(expression.Target);
|
||||
if (target.Type is not NubArrayType arrayType)
|
||||
{
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Cannot use array indexer on type {target.Type}").At(expression).Build());
|
||||
}
|
||||
|
||||
return new ArrayIndexAccessNode(expression.Tokens, arrayType.ElementType, target, index);
|
||||
return target.Type switch
|
||||
{
|
||||
NubArrayType arrayType => new ArrayIndexAccessNode(expression.Tokens, arrayType.ElementType, target, index),
|
||||
NubConstArrayType constArrayType => new ConstArrayIndexAccessNode(expression.Tokens, constArrayType.ElementType, target, index),
|
||||
NubSliceType sliceType => new SliceIndexAccessNode(expression.Tokens, sliceType.ElementType, target, index),
|
||||
_ => throw new TypeCheckerException(Diagnostic.Error($"Cannot use array indexer on type {target.Type}").At(expression).Build())
|
||||
};
|
||||
}
|
||||
|
||||
private ArrayInitializerNode CheckArrayInitializer(ArrayInitializerSyntax expression)
|
||||
@@ -808,12 +823,13 @@ public sealed class TypeChecker
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ArrayTypeSyntax arr => new NubArrayType(ResolveType(arr.BaseType)),
|
||||
BoolTypeSyntax => new NubBoolType(),
|
||||
CStringTypeSyntax => new NubCStringType(),
|
||||
IntTypeSyntax i => new NubIntType(i.Signed, i.Width),
|
||||
FloatTypeSyntax f => new NubFloatType(f.Width),
|
||||
FuncTypeSyntax func => new NubFuncType(func.Parameters.Select(ResolveType).ToList(), ResolveType(func.ReturnType)),
|
||||
ArrayTypeSyntax arr => new NubArrayType(ResolveType(arr.BaseType)),
|
||||
SliceTypeSyntax slice => new NubSliceType(ResolveType(slice.BaseType)),
|
||||
ConstArrayTypeSyntax arr => new NubConstArrayType(ResolveType(arr.BaseType), arr.Size),
|
||||
PointerTypeSyntax ptr => new NubPointerType(ResolveType(ptr.BaseType)),
|
||||
StringTypeSyntax => new NubStringType(),
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Generator
|
||||
return $"_t{++_tmpIndex}";
|
||||
}
|
||||
|
||||
private string MapNameWithType(NubType nubType, string name)
|
||||
private static string MapNameWithType(NubType nubType, string name)
|
||||
{
|
||||
var prefix = "";
|
||||
var postfix = "";
|
||||
@@ -46,8 +46,9 @@ public class Generator
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
NubSliceType sliceType => throw new NotImplementedException(),
|
||||
NubConstArrayType constArrayType => MapBaseType(constArrayType.ElementType),
|
||||
NubArrayType arrayType => MapBaseType(arrayType.ElementType),
|
||||
NubConstArrayType arrayType => MapBaseType(arrayType.ElementType),
|
||||
NubBoolType => "bool",
|
||||
NubCStringType => "char",
|
||||
NubFloatType floatType => floatType.Width switch
|
||||
@@ -121,6 +122,22 @@ public class Generator
|
||||
|
||||
_writer.WriteLine();
|
||||
|
||||
// note(nub31): declare extern functions
|
||||
foreach (var funcNode in _compilationUnit.Functions)
|
||||
{
|
||||
if (funcNode.Body != null) continue;
|
||||
|
||||
EmitLine(funcNode.Tokens.FirstOrDefault());
|
||||
var parameters = funcNode.Prototype.Parameters.Count != 0
|
||||
? string.Join(", ", funcNode.Prototype.Parameters.Select(x => MapNameWithType(x.Type, x.Name)))
|
||||
: "void";
|
||||
|
||||
var name = FuncName(funcNode.Module, funcNode.Name, funcNode.Prototype.ExternSymbol);
|
||||
_writer.WriteLine($"{MapNameWithType(funcNode.Prototype.ReturnType, name)}({parameters});");
|
||||
}
|
||||
|
||||
_writer.WriteLine();
|
||||
|
||||
// note(nub31): Normal functions
|
||||
foreach (var funcNode in _compilationUnit.Functions)
|
||||
{
|
||||
@@ -317,7 +334,7 @@ public class Generator
|
||||
|
||||
private void EmitVariableDeclaration(VariableDeclarationNode variableDeclarationNode)
|
||||
{
|
||||
if (variableDeclarationNode.Assignment != null)
|
||||
if (variableDeclarationNode.Assignment is { Type: not NubArrayType and not NubConstArrayType })
|
||||
{
|
||||
var value = EmitExpression(variableDeclarationNode.Assignment);
|
||||
_writer.WriteLine($"{MapNameWithType(variableDeclarationNode.Type, variableDeclarationNode.Name)} = {value};");
|
||||
@@ -343,6 +360,8 @@ public class Generator
|
||||
ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode),
|
||||
BinaryExpressionNode binaryExpressionNode => EmitBinaryExpression(binaryExpressionNode),
|
||||
BoolLiteralNode boolLiteralNode => EmitBoolLiteral(boolLiteralNode),
|
||||
ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode),
|
||||
ConstArrayInitializerNode constArrayInitializerNode => EmitConstArrayInitializer(constArrayInitializerNode),
|
||||
ConvertFloatNode convertFloatNode => EmitConvertFloat(convertFloatNode),
|
||||
ConvertIntNode convertIntNode => EmitConvertInt(convertIntNode),
|
||||
CStringLiteralNode cStringLiteralNode => EmitCStringLiteral(cStringLiteralNode),
|
||||
@@ -357,6 +376,7 @@ public class Generator
|
||||
LValueIdentifierNode lValueIdentifierNode => EmitLValueIdentifier(lValueIdentifierNode),
|
||||
RValueIdentifierNode rValueIdentifierNode => EmitRValueIdentifier(rValueIdentifierNode),
|
||||
SizeBuiltinNode sizeBuiltinNode => EmitSizeBuiltin(sizeBuiltinNode),
|
||||
SliceIndexAccessNode sliceIndexAccessNode => EmitSliceArrayIndexAccess(sliceIndexAccessNode),
|
||||
StringLiteralNode stringLiteralNode => EmitStringLiteral(stringLiteralNode),
|
||||
StructFieldAccessNode structFieldAccessNode => EmitStructFieldAccess(structFieldAccessNode),
|
||||
StructInitializerNode structInitializerNode => EmitStructInitializer(structInitializerNode),
|
||||
@@ -416,6 +436,19 @@ public class Generator
|
||||
return boolLiteralNode.Value ? "true" : "false";
|
||||
}
|
||||
|
||||
private string EmitConstArrayIndexAccess(ConstArrayIndexAccessNode constArrayIndexAccessNode)
|
||||
{
|
||||
var array = EmitExpression(constArrayIndexAccessNode.Target);
|
||||
var index = EmitExpression(constArrayIndexAccessNode.Index);
|
||||
// todo(nub31): We can emit bounds checking here
|
||||
return $"{array}[{index}]";
|
||||
}
|
||||
|
||||
private string EmitConstArrayInitializer(ConstArrayInitializerNode constArrayInitializerNode)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private string EmitConvertFloat(ConvertFloatNode convertFloatNode)
|
||||
{
|
||||
var value = EmitExpression(convertFloatNode.Value);
|
||||
@@ -544,6 +577,14 @@ public class Generator
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private string EmitSliceArrayIndexAccess(SliceIndexAccessNode sliceIndexAccessNode)
|
||||
{
|
||||
var value = EmitExpression(sliceIndexAccessNode.Target);
|
||||
var index = EmitExpression(sliceIndexAccessNode.Index);
|
||||
// todo(nub31): We can emit bounds checking here
|
||||
return $"{value}.data[{index}]";
|
||||
}
|
||||
|
||||
private string EmitStringLiteral(StringLiteralNode stringLiteralNode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -530,12 +530,21 @@ public sealed class Parser
|
||||
return expr;
|
||||
}
|
||||
|
||||
private ArrayInitializerSyntax ParseArrayInitializer(int startIndex)
|
||||
private ExpressionSyntax ParseArrayInitializer(int startIndex)
|
||||
{
|
||||
var capacity = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type);
|
||||
if (TryExpectIntLiteral(out var intLiteral))
|
||||
{
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
return new ConstArrayInitializerSyntax(GetTokens(startIndex), Convert.ToInt64(intLiteral.Value, intLiteral.Base), type);
|
||||
}
|
||||
else
|
||||
{
|
||||
var capacity = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type);
|
||||
}
|
||||
}
|
||||
|
||||
private StructInitializerSyntax ParseStructInitializer(int startIndex)
|
||||
@@ -707,13 +716,19 @@ public sealed class Parser
|
||||
{
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var baseType = ParseType();
|
||||
return new ConstArrayTypeSyntax(GetTokens(startIndex), baseType, int.Parse(intLiteral.Value));
|
||||
return new ConstArrayTypeSyntax(GetTokens(startIndex), baseType, Convert.ToInt64(intLiteral.Value, intLiteral.Base));
|
||||
}
|
||||
else if (TryExpectSymbol(Symbol.QuestionMark))
|
||||
{
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var baseType = ParseType();
|
||||
return new ArrayTypeSyntax(GetTokens(startIndex), baseType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var baseType = ParseType();
|
||||
return new ArrayTypeSyntax(GetTokens(startIndex), baseType);
|
||||
return new SliceTypeSyntax(GetTokens(startIndex), baseType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,8 @@ public record ModuleIdentifierSyntax(List<Token> Tokens, string Module, string N
|
||||
|
||||
public record ArrayInitializerSyntax(List<Token> Tokens, ExpressionSyntax Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record ConstArrayInitializerSyntax(List<Token> Tokens, long Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record ArrayIndexAccessSyntax(List<Token> Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record AddressOfSyntax(List<Token> Tokens, ExpressionSyntax Target) : ExpressionSyntax(Tokens);
|
||||
@@ -134,9 +136,11 @@ public record StringTypeSyntax(List<Token> Tokens) : TypeSyntax(Tokens);
|
||||
|
||||
public record CStringTypeSyntax(List<Token> Tokens) : TypeSyntax(Tokens);
|
||||
|
||||
public record SliceTypeSyntax(List<Token> Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens);
|
||||
|
||||
public record ArrayTypeSyntax(List<Token> Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens);
|
||||
|
||||
public record ConstArrayTypeSyntax(List<Token> Tokens, TypeSyntax BaseType, int Size) : TypeSyntax(Tokens);
|
||||
public record ConstArrayTypeSyntax(List<Token> Tokens, TypeSyntax BaseType, long Size) : TypeSyntax(Tokens);
|
||||
|
||||
public record CustomTypeSyntax(List<Token> Tokens, string Module, string Name) : TypeSyntax(Tokens);
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ public enum Symbol
|
||||
Module,
|
||||
Import,
|
||||
At,
|
||||
QuestionMark
|
||||
}
|
||||
|
||||
public abstract record Token(SourceSpan Span);
|
||||
|
||||
@@ -56,6 +56,7 @@ public sealed class Tokenizer
|
||||
[['%']] = Symbol.Percent,
|
||||
[['|']] = Symbol.Pipe,
|
||||
[['@']] = Symbol.At,
|
||||
[['?']] = Symbol.QuestionMark,
|
||||
};
|
||||
|
||||
private static readonly (char[] Pattern, Symbol Symbol)[] OrderedSymbols = Symbols
|
||||
|
||||
Reference in New Issue
Block a user