Compare commits
10 Commits
ec422cf1cd
...
0c35bc052c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c35bc052c | ||
|
|
2641357832 | ||
|
|
9f91e42d63 | ||
|
|
a7c45784b9 | ||
|
|
7486f2fd4e | ||
|
|
6775a09ba9 | ||
|
|
0f191b21bc | ||
|
|
bfe8b7b18e | ||
|
|
db5d444cf2 | ||
|
|
08ae39b5ed |
@@ -68,368 +68,10 @@ public static class AstExtensions
|
|||||||
public static Node? DeepestNodeAtPosition(this CompilationUnit compilationUnit, int line, int character)
|
public static Node? DeepestNodeAtPosition(this CompilationUnit compilationUnit, int line, int character)
|
||||||
{
|
{
|
||||||
return compilationUnit.Functions
|
return compilationUnit.Functions
|
||||||
.SelectMany(x => x.EnumerateDescendantsAndSelf())
|
.SelectMany(x => x.DescendantsAndSelf())
|
||||||
.Where(n => n.ContainsPosition(line, character))
|
.Where(n => n.ContainsPosition(line, character))
|
||||||
.OrderBy(n => n.Tokens.First().Span.Start.Line)
|
.OrderBy(n => n.Tokens.First().Span.Start.Line)
|
||||||
.ThenBy(n => n.Tokens.First().Span.Start.Column)
|
.ThenBy(n => n.Tokens.First().Span.Start.Column)
|
||||||
.LastOrDefault();
|
.LastOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node? DeepestNodeAtPosition(this Node node, int line, int character)
|
|
||||||
{
|
|
||||||
return node.EnumerateDescendantsAndSelf()
|
|
||||||
.Where(n => n.ContainsPosition(line, character))
|
|
||||||
.OrderBy(n => n.Tokens.First().Span.Start.Line)
|
|
||||||
.ThenBy(n => n.Tokens.First().Span.Start.Column)
|
|
||||||
.LastOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<Node> EnumerateDescendantsAndSelf(this Node node)
|
|
||||||
{
|
|
||||||
yield return node;
|
|
||||||
|
|
||||||
switch (node)
|
|
||||||
{
|
|
||||||
case FuncNode func:
|
|
||||||
{
|
|
||||||
foreach (var n in func.Prototype.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (func.Body != null)
|
|
||||||
{
|
|
||||||
foreach (var n in func.Body.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FuncPrototypeNode proto:
|
|
||||||
{
|
|
||||||
foreach (var n in proto.Parameters.SelectMany(param => param.EnumerateDescendantsAndSelf()))
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BlockNode block:
|
|
||||||
{
|
|
||||||
foreach (var n in block.Statements.SelectMany(stmt => stmt.EnumerateDescendantsAndSelf()))
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case StatementFuncCallNode stmtCall:
|
|
||||||
{
|
|
||||||
foreach (var n in stmtCall.FuncCall.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ReturnNode { Value: not null } ret:
|
|
||||||
{
|
|
||||||
foreach (var n in ret.Value.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AssignmentNode assign:
|
|
||||||
{
|
|
||||||
foreach (var n in assign.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in assign.Value.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IfNode ifNode:
|
|
||||||
{
|
|
||||||
foreach (var n in ifNode.Condition.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in ifNode.Body.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ifNode.Else.HasValue)
|
|
||||||
{
|
|
||||||
if (ifNode.Else.Value.IsCase1(out var elseIfNode))
|
|
||||||
{
|
|
||||||
foreach (var n in elseIfNode.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ifNode.Else.Value.IsCase2(out var elseNode))
|
|
||||||
{
|
|
||||||
foreach (var n in elseNode.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VariableDeclarationNode decl:
|
|
||||||
{
|
|
||||||
if (decl.Assignment != null)
|
|
||||||
{
|
|
||||||
foreach (var n in decl.Assignment.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WhileNode whileNode:
|
|
||||||
{
|
|
||||||
foreach (var n in whileNode.Condition.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in whileNode.Body.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ForSliceNode forSlice:
|
|
||||||
{
|
|
||||||
foreach (var n in forSlice.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in forSlice.Body.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ForConstArrayNode forConst:
|
|
||||||
{
|
|
||||||
foreach (var n in forConst.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in forConst.Body.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DeferNode defer:
|
|
||||||
{
|
|
||||||
foreach (var n in defer.Statement.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinaryExpressionNode bin:
|
|
||||||
{
|
|
||||||
foreach (var n in bin.Left.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in bin.Right.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case UnaryExpressionNode unary:
|
|
||||||
{
|
|
||||||
foreach (var n in unary.Operand.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FuncCallNode call:
|
|
||||||
{
|
|
||||||
foreach (var n in call.Expression.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in call.Parameters.SelectMany(param => param.EnumerateDescendantsAndSelf()))
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ArrayInitializerNode arrInit:
|
|
||||||
{
|
|
||||||
foreach (var n in arrInit.Values.SelectMany(val => val.EnumerateDescendantsAndSelf()))
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConstArrayInitializerNode constArrInit:
|
|
||||||
{
|
|
||||||
foreach (var n in constArrInit.Values.SelectMany(val => val.EnumerateDescendantsAndSelf()))
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ArrayIndexAccessNode arrIndex:
|
|
||||||
{
|
|
||||||
foreach (var n in arrIndex.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in arrIndex.Index.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConstArrayIndexAccessNode constArrIndex:
|
|
||||||
{
|
|
||||||
foreach (var n in constArrIndex.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in constArrIndex.Index.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SliceIndexAccessNode sliceIndex:
|
|
||||||
{
|
|
||||||
foreach (var n in sliceIndex.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var n in sliceIndex.Index.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AddressOfNode addr:
|
|
||||||
{
|
|
||||||
foreach (var n in addr.LValue.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case StructFieldAccessNode field:
|
|
||||||
{
|
|
||||||
foreach (var n in field.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case StructInitializerNode structInit:
|
|
||||||
{
|
|
||||||
foreach (var n in structInit.Initializers.SelectMany(kv => kv.Value.EnumerateDescendantsAndSelf()))
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DereferenceNode deref:
|
|
||||||
{
|
|
||||||
foreach (var n in deref.Target.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConvertIntNode convInt:
|
|
||||||
{
|
|
||||||
foreach (var n in convInt.Value.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConvertFloatNode convFloat:
|
|
||||||
{
|
|
||||||
foreach (var n in convFloat.Value.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConvertCStringToStringNode convStr:
|
|
||||||
{
|
|
||||||
foreach (var n in convStr.Value.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FloatToIntBuiltinNode ftoi:
|
|
||||||
{
|
|
||||||
foreach (var n in ftoi.Value.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConstArrayToSliceNode constSlice:
|
|
||||||
{
|
|
||||||
foreach (var n in constSlice.Array.EnumerateDescendantsAndSelf())
|
|
||||||
{
|
|
||||||
yield return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -150,9 +150,8 @@ internal class CompletionHandler(WorkspaceManager workspaceManager) : Completion
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var variables = function
|
var variables = function.Body!
|
||||||
.Body!
|
.Descendants()
|
||||||
.EnumerateDescendantsAndSelf()
|
|
||||||
.OfType<VariableDeclarationNode>();
|
.OfType<VariableDeclarationNode>();
|
||||||
|
|
||||||
foreach (var variable in variables)
|
foreach (var variable in variables)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ internal class DefinitionHandler(WorkspaceManager workspaceManager) : Definition
|
|||||||
}
|
}
|
||||||
|
|
||||||
var variable = function?.Body?
|
var variable = function?.Body?
|
||||||
.EnumerateDescendantsAndSelf()
|
.Descendants()
|
||||||
.OfType<VariableDeclarationNode>()
|
.OfType<VariableDeclarationNode>()
|
||||||
.FirstOrDefault(x => x.Name == variableIdentifierNode.Name);
|
.FirstOrDefault(x => x.Name == variableIdentifierNode.Name);
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
using NubLang.Ast;
|
using NubLang.Ast;
|
||||||
using NubLang.Generation;
|
|
||||||
using NubLang.Syntax;
|
using NubLang.Syntax;
|
||||||
using OmniSharp.Extensions.LanguageServer.Protocol;
|
using OmniSharp.Extensions.LanguageServer.Protocol;
|
||||||
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
|
|
||||||
|
|
||||||
namespace NubLang.LSP;
|
namespace NubLang.LSP;
|
||||||
|
|
||||||
public class WorkspaceManager(DiagnosticsPublisher diagnosticsPublisher, ILanguageServerFacade server)
|
public class WorkspaceManager(DiagnosticsPublisher diagnosticsPublisher)
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, SyntaxTree> _syntaxTrees = new();
|
private readonly Dictionary<string, SyntaxTree> _syntaxTrees = new();
|
||||||
private readonly Dictionary<string, CompilationUnit> _compilationUnits = new();
|
private readonly Dictionary<string, CompilationUnit> _compilationUnits = new();
|
||||||
@@ -29,47 +27,37 @@ public class WorkspaceManager(DiagnosticsPublisher diagnosticsPublisher, ILangua
|
|||||||
_syntaxTrees[path] = parseResult;
|
_syntaxTrees[path] = parseResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
Generate();
|
foreach (var (fsPath, syntaxTree) in _syntaxTrees)
|
||||||
|
{
|
||||||
|
var modules = Module.Collect(_syntaxTrees.Select(x => x.Value).ToList());
|
||||||
|
|
||||||
|
var typeChecker = new TypeChecker(syntaxTree, modules);
|
||||||
|
var result = typeChecker.Check();
|
||||||
|
diagnosticsPublisher.Publish(fsPath, typeChecker.Diagnostics);
|
||||||
|
_compilationUnits[fsPath] = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateFile(DocumentUri path)
|
public void UpdateFile(DocumentUri path)
|
||||||
{
|
{
|
||||||
var fsPath = path.GetFileSystemPath();
|
var fsPath = path.GetFileSystemPath();
|
||||||
|
|
||||||
var text = File.ReadAllText(fsPath);
|
var text = File.ReadAllText(fsPath);
|
||||||
var tokenizer = new Tokenizer(fsPath, text);
|
var tokenizer = new Tokenizer(fsPath, text);
|
||||||
|
|
||||||
tokenizer.Tokenize();
|
tokenizer.Tokenize();
|
||||||
diagnosticsPublisher.Publish(path, tokenizer.Diagnostics);
|
diagnosticsPublisher.Publish(path, tokenizer.Diagnostics);
|
||||||
|
|
||||||
var parser = new Parser();
|
var parser = new Parser();
|
||||||
var parseResult = parser.Parse(tokenizer.Tokens);
|
var syntaxTree = parser.Parse(tokenizer.Tokens);
|
||||||
diagnosticsPublisher.Publish(path, parser.Diagnostics);
|
diagnosticsPublisher.Publish(path, parser.Diagnostics);
|
||||||
|
_syntaxTrees[fsPath] = syntaxTree;
|
||||||
|
|
||||||
_syntaxTrees[fsPath] = parseResult;
|
|
||||||
|
|
||||||
Generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Generate()
|
|
||||||
{
|
|
||||||
var modules = Module.Collect(_syntaxTrees.Select(x => x.Value).ToList());
|
var modules = Module.Collect(_syntaxTrees.Select(x => x.Value).ToList());
|
||||||
|
|
||||||
foreach (var (documentUri, syntaxTree) in _syntaxTrees)
|
var typeChecker = new TypeChecker(syntaxTree, modules);
|
||||||
{
|
var result = typeChecker.Check();
|
||||||
var typeChecker = new TypeChecker(syntaxTree, modules);
|
diagnosticsPublisher.Publish(fsPath, typeChecker.Diagnostics);
|
||||||
var result = typeChecker.Check();
|
_compilationUnits[fsPath] = result;
|
||||||
diagnosticsPublisher.Publish(documentUri, typeChecker.Diagnostics);
|
|
||||||
_compilationUnits[documentUri] = result;
|
|
||||||
|
|
||||||
var generator = new Generator(result);
|
|
||||||
var c = generator.Emit();
|
|
||||||
|
|
||||||
server.SendNotification("nub/output", new
|
|
||||||
{
|
|
||||||
content = c,
|
|
||||||
uri = documentUri
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFile(DocumentUri path)
|
public void RemoveFile(DocumentUri path)
|
||||||
@@ -79,11 +67,6 @@ public class WorkspaceManager(DiagnosticsPublisher diagnosticsPublisher, ILangua
|
|||||||
_compilationUnits.Remove(fsPath);
|
_compilationUnits.Remove(fsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, CompilationUnit> GetCompilationUnits()
|
|
||||||
{
|
|
||||||
return _compilationUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompilationUnit? GetCompilationUnit(DocumentUri path)
|
public CompilationUnit? GetCompilationUnit(DocumentUri path)
|
||||||
{
|
{
|
||||||
return _compilationUnits.GetValueOrDefault(path.GetFileSystemPath());
|
return _compilationUnits.GetValueOrDefault(path.GetFileSystemPath());
|
||||||
|
|||||||
@@ -2,17 +2,62 @@ using NubLang.Syntax;
|
|||||||
|
|
||||||
namespace NubLang.Ast;
|
namespace NubLang.Ast;
|
||||||
|
|
||||||
public abstract record Node(List<Token> Tokens);
|
public abstract record Node(List<Token> Tokens)
|
||||||
|
{
|
||||||
|
public abstract IEnumerable<Node> Children();
|
||||||
|
|
||||||
|
public IEnumerable<Node> Descendants()
|
||||||
|
{
|
||||||
|
foreach (var child in Children())
|
||||||
|
{
|
||||||
|
foreach (var descendant in child.DescendantsAndSelf())
|
||||||
|
{
|
||||||
|
yield return descendant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Node> DescendantsAndSelf()
|
||||||
|
{
|
||||||
|
yield return this;
|
||||||
|
foreach (var descendant in Descendants())
|
||||||
|
{
|
||||||
|
yield return descendant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Definitions
|
#region Definitions
|
||||||
|
|
||||||
public abstract record DefinitionNode(List<Token> Tokens, string Module, string Name) : Node(Tokens);
|
public abstract record DefinitionNode(List<Token> Tokens, string Module, string Name) : Node(Tokens);
|
||||||
|
|
||||||
public record FuncParameterNode(List<Token> Tokens, string Name, NubType Type) : Node(Tokens);
|
public record FuncParameterNode(List<Token> Tokens, string Name, NubType Type) : Node(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record FuncPrototypeNode(List<Token> Tokens, string Module, string Name, string? ExternSymbol, List<FuncParameterNode> Parameters, NubType ReturnType) : Node(Tokens);
|
public record FuncPrototypeNode(List<Token> Tokens, string Module, string Name, string? ExternSymbol, List<FuncParameterNode> Parameters, NubType ReturnType) : Node(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return Parameters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record FuncNode(List<Token> Tokens, FuncPrototypeNode Prototype, BlockNode? Body) : DefinitionNode(Tokens, Prototype.Module, Prototype.Name);
|
public record FuncNode(List<Token> Tokens, FuncPrototypeNode Prototype, BlockNode? Body) : DefinitionNode(Tokens, Prototype.Module, Prototype.Name)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Prototype;
|
||||||
|
if (Body != null)
|
||||||
|
{
|
||||||
|
yield return Body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -22,29 +67,110 @@ public abstract record StatementNode(List<Token> Tokens) : Node(Tokens);
|
|||||||
|
|
||||||
public abstract record TerminalStatementNode(List<Token> Tokens) : StatementNode(Tokens);
|
public abstract record TerminalStatementNode(List<Token> Tokens) : StatementNode(Tokens);
|
||||||
|
|
||||||
public record BlockNode(List<Token> Tokens, List<StatementNode> Statements) : StatementNode(Tokens);
|
public record BlockNode(List<Token> Tokens, List<StatementNode> Statements) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return Statements;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record StatementFuncCallNode(List<Token> Tokens, FuncCallNode FuncCall) : StatementNode(Tokens);
|
public record StatementFuncCallNode(List<Token> Tokens, FuncCallNode FuncCall) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return FuncCall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ReturnNode(List<Token> Tokens, ExpressionNode? Value) : TerminalStatementNode(Tokens);
|
public record ReturnNode(List<Token> Tokens, ExpressionNode? Value) : TerminalStatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
if (Value != null) yield return Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record AssignmentNode(List<Token> Tokens, LValueExpressionNode Target, ExpressionNode Value) : StatementNode(Tokens);
|
public record AssignmentNode(List<Token> Tokens, LValueExpressionNode Target, ExpressionNode Value) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
yield return Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record IfNode(List<Token> Tokens, ExpressionNode Condition, BlockNode Body, Variant<IfNode, BlockNode>? Else) : StatementNode(Tokens);
|
public record IfNode(List<Token> Tokens, ExpressionNode Condition, BlockNode Body, Variant<IfNode, BlockNode>? Else) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Condition;
|
||||||
|
yield return Body;
|
||||||
|
if (Else.HasValue)
|
||||||
|
{
|
||||||
|
yield return Else.Value.Match<Node>(x => x, x => x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record VariableDeclarationNode(List<Token> Tokens, string Name, ExpressionNode? Assignment, NubType Type) : StatementNode(Tokens);
|
public record VariableDeclarationNode(List<Token> Tokens, string Name, ExpressionNode? Assignment, NubType Type) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
if (Assignment != null) yield return Assignment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ContinueNode(List<Token> Tokens) : TerminalStatementNode(Tokens);
|
public record ContinueNode(List<Token> Tokens) : TerminalStatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record BreakNode(List<Token> Tokens) : TerminalStatementNode(Tokens);
|
public record BreakNode(List<Token> Tokens) : TerminalStatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record WhileNode(List<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens);
|
public record WhileNode(List<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Condition;
|
||||||
|
yield return Body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ForSliceNode(List<Token> Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens);
|
public record ForSliceNode(List<Token> Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
yield return Body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ForConstArrayNode(List<Token> Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens);
|
public record ForConstArrayNode(List<Token> Tokens, string ElementName, string? IndexName, ExpressionNode Target, BlockNode Body) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
yield return Body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record DeferNode(List<Token> Tokens, StatementNode Statement) : StatementNode(Tokens);
|
public record DeferNode(List<Token> Tokens, StatementNode Statement) : StatementNode(Tokens)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Statement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -86,72 +212,255 @@ public abstract record RValueExpressionNode(List<Token> Tokens, NubType Type) :
|
|||||||
|
|
||||||
public abstract record IntermediateExpression(List<Token> Tokens) : ExpressionNode(Tokens, new NubVoidType());
|
public abstract record IntermediateExpression(List<Token> Tokens) : ExpressionNode(Tokens, new NubVoidType());
|
||||||
|
|
||||||
public record StringLiteralNode(List<Token> Tokens, string Value) : RValueExpressionNode(Tokens, new NubStringType());
|
public record StringLiteralNode(List<Token> Tokens, string Value) : RValueExpressionNode(Tokens, new NubStringType())
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record CStringLiteralNode(List<Token> Tokens, string Value) : RValueExpressionNode(Tokens, new NubCStringType());
|
public record CStringLiteralNode(List<Token> Tokens, string Value) : RValueExpressionNode(Tokens, new NubCStringType())
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record I8LiteralNode(List<Token> Tokens, sbyte Value) : RValueExpressionNode(Tokens, new NubIntType(true, 8));
|
public record I8LiteralNode(List<Token> Tokens, sbyte Value) : RValueExpressionNode(Tokens, new NubIntType(true, 8))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record I16LiteralNode(List<Token> Tokens, short Value) : RValueExpressionNode(Tokens, new NubIntType(true, 16));
|
public record I16LiteralNode(List<Token> Tokens, short Value) : RValueExpressionNode(Tokens, new NubIntType(true, 16))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record I32LiteralNode(List<Token> Tokens, int Value) : RValueExpressionNode(Tokens, new NubIntType(true, 32));
|
public record I32LiteralNode(List<Token> Tokens, int Value) : RValueExpressionNode(Tokens, new NubIntType(true, 32))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record I64LiteralNode(List<Token> Tokens, long Value) : RValueExpressionNode(Tokens, new NubIntType(true, 64));
|
public record I64LiteralNode(List<Token> Tokens, long Value) : RValueExpressionNode(Tokens, new NubIntType(true, 64))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record U8LiteralNode(List<Token> Tokens, byte Value) : RValueExpressionNode(Tokens, new NubIntType(false, 8));
|
public record U8LiteralNode(List<Token> Tokens, byte Value) : RValueExpressionNode(Tokens, new NubIntType(false, 8))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record U16LiteralNode(List<Token> Tokens, ushort Value) : RValueExpressionNode(Tokens, new NubIntType(false, 16));
|
public record U16LiteralNode(List<Token> Tokens, ushort Value) : RValueExpressionNode(Tokens, new NubIntType(false, 16))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record U32LiteralNode(List<Token> Tokens, uint Value) : RValueExpressionNode(Tokens, new NubIntType(false, 32));
|
public record U32LiteralNode(List<Token> Tokens, uint Value) : RValueExpressionNode(Tokens, new NubIntType(false, 32))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record U64LiteralNode(List<Token> Tokens, ulong Value) : RValueExpressionNode(Tokens, new NubIntType(false, 64));
|
public record U64LiteralNode(List<Token> Tokens, ulong Value) : RValueExpressionNode(Tokens, new NubIntType(false, 64))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record Float32LiteralNode(List<Token> Tokens, float Value) : RValueExpressionNode(Tokens, new NubFloatType(32));
|
public record Float32LiteralNode(List<Token> Tokens, float Value) : RValueExpressionNode(Tokens, new NubFloatType(32))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record Float64LiteralNode(List<Token> Tokens, double Value) : RValueExpressionNode(Tokens, new NubFloatType(64));
|
public record Float64LiteralNode(List<Token> Tokens, double Value) : RValueExpressionNode(Tokens, new NubFloatType(64))
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record BoolLiteralNode(List<Token> Tokens, NubType Type, bool Value) : RValueExpressionNode(Tokens, Type);
|
public record BoolLiteralNode(List<Token> Tokens, NubType Type, bool Value) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record BinaryExpressionNode(List<Token> Tokens, NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Tokens, Type);
|
public record BinaryExpressionNode(List<Token> Tokens, NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Left;
|
||||||
|
yield return Right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record UnaryExpressionNode(List<Token> Tokens, NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Tokens, Type);
|
public record UnaryExpressionNode(List<Token> Tokens, NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Operand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record FuncCallNode(List<Token> Tokens, NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Tokens, Type);
|
public record FuncCallNode(List<Token> Tokens, NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Expression;
|
||||||
|
foreach (var expressionNode in Parameters)
|
||||||
|
{
|
||||||
|
yield return expressionNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record VariableIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type);
|
public record VariableIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record FuncIdentifierNode(List<Token> Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type);
|
public record FuncIdentifierNode(List<Token> Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, List<ExpressionNode> Values) : RValueExpressionNode(Tokens, Type);
|
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, List<ExpressionNode> Values) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ConstArrayInitializerNode(List<Token> Tokens, NubType Type, List<ExpressionNode> Values) : RValueExpressionNode(Tokens, Type);
|
public record ConstArrayInitializerNode(List<Token> Tokens, NubType Type, List<ExpressionNode> Values) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
public record ArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
yield return Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ConstArrayIndexAccessNode(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 override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
yield return Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record SliceIndexAccessNode(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 override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
yield return Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record AddressOfNode(List<Token> Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type);
|
public record AddressOfNode(List<Token> Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return LValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record StructFieldAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type);
|
public record StructFieldAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record StructInitializerNode(List<Token> Tokens, NubType Type, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(Tokens, Type);
|
public record StructInitializerNode(List<Token> Tokens, NubType Type, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
foreach (var initializer in Initializers)
|
||||||
|
{
|
||||||
|
yield return initializer.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record DereferenceNode(List<Token> Tokens, NubType Type, ExpressionNode Target) : LValueExpressionNode(Tokens, Type);
|
public record DereferenceNode(List<Token> Tokens, NubType Type, ExpressionNode Target) : LValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ConvertIntNode(List<Token> Tokens, ExpressionNode Value, int StartWidth, int TargetWidth, bool StartSignedness, bool TargetSignedness) : RValueExpressionNode(Tokens, new NubIntType(TargetSignedness, TargetWidth));
|
public record SizeNode(List<Token> Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ConvertFloatNode(List<Token> Tokens, ExpressionNode Value, int StartWidth, int TargetWidth) : RValueExpressionNode(Tokens, new NubFloatType(TargetWidth));
|
public record CastNode(List<Token> Tokens, NubType Type, ExpressionNode Value) : RValueExpressionNode(Tokens, Type)
|
||||||
|
{
|
||||||
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
|
yield return Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ConvertCStringToStringNode(List<Token> Tokens, ExpressionNode Value) : RValueExpressionNode(Tokens, new NubStringType());
|
public record EnumReferenceIntermediateNode(List<Token> Tokens, string Module, string Name) : IntermediateExpression(Tokens)
|
||||||
|
{
|
||||||
public record SizeBuiltinNode(List<Token> Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type);
|
public override IEnumerable<Node> Children()
|
||||||
|
{
|
||||||
public record FloatToIntBuiltinNode(List<Token> Tokens, NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Tokens, Type);
|
return [];
|
||||||
|
}
|
||||||
public record ConstArrayToSliceNode(List<Token> Tokens, NubType Type, ExpressionNode Array) : RValueExpressionNode(Tokens, Type);
|
}
|
||||||
|
|
||||||
public record EnumReferenceIntermediateNode(List<Token> Tokens, string Module, string Name) : IntermediateExpression(Tokens);
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -309,69 +309,97 @@ public sealed class TypeChecker
|
|||||||
FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType),
|
FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType),
|
||||||
MemberAccessSyntax expression => CheckMemberAccess(expression, expectedType),
|
MemberAccessSyntax expression => CheckMemberAccess(expression, expectedType),
|
||||||
StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType),
|
StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType),
|
||||||
InterpretBuiltinSyntax expression => CheckExpression(expression.Target, expectedType) with { Type = ResolveType(expression.Type) },
|
InterpretSyntax expression => CheckExpression(expression.Target, expectedType) with { Type = ResolveType(expression.Type) },
|
||||||
SizeBuiltinSyntax expression => new SizeBuiltinNode(node.Tokens, new NubIntType(false, 64), ResolveType(expression.Type)),
|
SizeSyntax expression => new SizeNode(node.Tokens, new NubIntType(false, 64), ResolveType(expression.Type)),
|
||||||
FloatToIntBuiltinSyntax expression => CheckFloatToInt(expression, expectedType),
|
CastSyntax expression => CheckCast(expression, expectedType),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (expectedType)
|
if (expectedType != null)
|
||||||
{
|
{
|
||||||
// note(nub31): Implicit conversion of const array to unsized array
|
if (result.Type == expectedType)
|
||||||
case NubArrayType when result.Type is NubConstArrayType constArrayType:
|
|
||||||
{
|
|
||||||
return result with { Type = new NubArrayType(constArrayType.ElementType) };
|
|
||||||
}
|
|
||||||
// note(nub31): Implicit conversion of const array to slice
|
|
||||||
case NubSliceType when result.Type is NubConstArrayType constArrayType:
|
|
||||||
{
|
|
||||||
return new ConstArrayToSliceNode(result.Tokens, new NubSliceType(constArrayType.ElementType), result);
|
|
||||||
}
|
|
||||||
// note(nub31): Implicit conversion of int to larger int
|
|
||||||
case NubIntType expectedIntType when result.Type is NubIntType intType && expectedIntType.Width > intType.Width:
|
|
||||||
{
|
|
||||||
return new ConvertIntNode(result.Tokens, result, intType.Width, expectedIntType.Width, intType.Signed, expectedIntType.Signed);
|
|
||||||
}
|
|
||||||
// note(nub31): Implicit conversion of f32 to f64
|
|
||||||
case NubFloatType expectedFloatType when result.Type is NubFloatType floatType && expectedFloatType.Width > floatType.Width:
|
|
||||||
{
|
|
||||||
return new ConvertFloatNode(result.Tokens, result, floatType.Width, expectedFloatType.Width);
|
|
||||||
}
|
|
||||||
// note(nub31): Implicit conversion of cstring to string
|
|
||||||
case NubStringType when result.Type is NubCStringType:
|
|
||||||
{
|
|
||||||
return new ConvertCStringToStringNode(result.Tokens, result);
|
|
||||||
}
|
|
||||||
// note(nub31): No implicit conversion was possible or the result value was already the correct type
|
|
||||||
default:
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsCastAllowed(result.Type, expectedType))
|
||||||
|
{
|
||||||
|
return new CastNode(result.Tokens, expectedType, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo(nub31): Infer int type instead of explicit type syntax
|
private ExpressionNode CheckCast(CastSyntax expression, NubType? expectedType)
|
||||||
private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression, NubType? _)
|
|
||||||
{
|
{
|
||||||
var value = CheckExpression(expression.Value);
|
if (expectedType == null)
|
||||||
if (value.Type is not NubFloatType sourceFloatType)
|
|
||||||
{
|
{
|
||||||
throw new TypeCheckerException(Diagnostic
|
throw new TypeCheckerException(Diagnostic
|
||||||
.Error("Source type of float to int conversion must be an float")
|
.Error("Unable to infer target type of cast")
|
||||||
.At(expression.Value)
|
.At(expression)
|
||||||
|
.WithHelp("Specify target type where value is used")
|
||||||
.Build());
|
.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetType = ResolveType(expression.Type);
|
var value = CheckExpression(expression.Value, expectedType);
|
||||||
if (targetType is not NubIntType targetIntType)
|
|
||||||
|
if (value.Type == expectedType)
|
||||||
|
{
|
||||||
|
Diagnostics.Add(Diagnostic
|
||||||
|
.Warning("Target type of cast is same as the value. Cast is unnecessary")
|
||||||
|
.At(expression)
|
||||||
|
.Build());
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsCastAllowed(value.Type, expectedType, false))
|
||||||
{
|
{
|
||||||
throw new TypeCheckerException(Diagnostic
|
throw new TypeCheckerException(Diagnostic
|
||||||
.Error("Target type of float to int conversion must be an integer")
|
.Error($"Cannot cast from {value.Type} to {expectedType}")
|
||||||
.At(expression.Type)
|
|
||||||
.Build());
|
.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FloatToIntBuiltinNode(expression.Tokens, targetIntType, value, sourceFloatType, targetIntType);
|
return new CastNode(expression.Tokens, expectedType, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsCastAllowed(NubType from, NubType to, bool strict = true)
|
||||||
|
{
|
||||||
|
// note(nub31): Implicit casts
|
||||||
|
switch (from)
|
||||||
|
{
|
||||||
|
case NubIntType fromInt when to is NubIntType toInt && fromInt.Width < toInt.Width:
|
||||||
|
case NubPointerType when to is NubPointerType { BaseType: NubVoidType }:
|
||||||
|
case NubConstArrayType constArrayType1 when to is NubArrayType arrayType && constArrayType1.ElementType == arrayType.ElementType:
|
||||||
|
case NubConstArrayType constArrayType3 when to is NubSliceType sliceType2 && constArrayType3.ElementType == sliceType2.ElementType:
|
||||||
|
case NubCStringType when to is NubStringType:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strict)
|
||||||
|
{
|
||||||
|
// note(nub31): Explicit casts
|
||||||
|
switch (from)
|
||||||
|
{
|
||||||
|
case NubIntType when to is NubIntType:
|
||||||
|
case NubIntType when to is NubFloatType:
|
||||||
|
case NubFloatType when to is NubIntType:
|
||||||
|
case NubFloatType when to is NubFloatType:
|
||||||
|
case NubPointerType when to is NubPointerType:
|
||||||
|
case NubPointerType when to is NubIntType:
|
||||||
|
case NubIntType when to is NubPointerType:
|
||||||
|
case NubCStringType when to is NubPointerType { BaseType: NubIntType { Width: 8 } }:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AddressOfNode CheckAddressOf(AddressOfSyntax expression, NubType? expectedType)
|
private AddressOfNode CheckAddressOf(AddressOfSyntax expression, NubType? expectedType)
|
||||||
@@ -499,6 +527,13 @@ public sealed class TypeChecker
|
|||||||
}
|
}
|
||||||
|
|
||||||
var right = CheckExpression(expression.Right, left.Type);
|
var right = CheckExpression(expression.Right, left.Type);
|
||||||
|
if (right.Type != left.Type)
|
||||||
|
{
|
||||||
|
throw new TypeCheckerException(Diagnostic
|
||||||
|
.Error($"Expected type {left.Type} from left side of binary expression, but got {right.Type}")
|
||||||
|
.At(expression.Right)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
|
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
|
||||||
}
|
}
|
||||||
@@ -517,6 +552,13 @@ public sealed class TypeChecker
|
|||||||
}
|
}
|
||||||
|
|
||||||
var right = CheckExpression(expression.Right, left.Type);
|
var right = CheckExpression(expression.Right, left.Type);
|
||||||
|
if (right.Type != left.Type)
|
||||||
|
{
|
||||||
|
throw new TypeCheckerException(Diagnostic
|
||||||
|
.Error($"Expected type {left.Type} from left side of binary expression, but got {right.Type}")
|
||||||
|
.At(expression.Right)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
|
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
|
||||||
}
|
}
|
||||||
@@ -533,21 +575,36 @@ public sealed class TypeChecker
|
|||||||
}
|
}
|
||||||
|
|
||||||
var right = CheckExpression(expression.Right, left.Type);
|
var right = CheckExpression(expression.Right, left.Type);
|
||||||
|
if (right.Type != left.Type)
|
||||||
|
{
|
||||||
|
throw new TypeCheckerException(Diagnostic
|
||||||
|
.Error($"Expected type {left.Type} from left side of binary expression, but got {right.Type}")
|
||||||
|
.At(expression.Right)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
|
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
|
||||||
}
|
}
|
||||||
case BinaryOperatorSyntax.Plus:
|
case BinaryOperatorSyntax.Plus:
|
||||||
{
|
{
|
||||||
var left = CheckExpression(expression.Left, expectedType);
|
var left = CheckExpression(expression.Left, expectedType);
|
||||||
if (left.Type is not NubIntType and not NubFloatType and not NubStringType and not NubCStringType)
|
if (left.Type is not NubIntType and not NubFloatType)
|
||||||
{
|
{
|
||||||
throw new TypeCheckerException(Diagnostic
|
throw new TypeCheckerException(Diagnostic
|
||||||
.Error("The plus operator must be used with int, float, cstring or string types")
|
.Error("The plus operator must only be used with int and float types")
|
||||||
.At(expression.Left)
|
.At(expression.Left)
|
||||||
.Build());
|
.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
var right = CheckExpression(expression.Right, left.Type);
|
var right = CheckExpression(expression.Right, left.Type);
|
||||||
|
if (right.Type != left.Type)
|
||||||
|
{
|
||||||
|
throw new TypeCheckerException(Diagnostic
|
||||||
|
.Error($"Expected type {left.Type} from left side of binary expression, but got {right.Type}")
|
||||||
|
.At(expression.Right)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
||||||
}
|
}
|
||||||
case BinaryOperatorSyntax.Minus:
|
case BinaryOperatorSyntax.Minus:
|
||||||
@@ -565,6 +622,13 @@ public sealed class TypeChecker
|
|||||||
}
|
}
|
||||||
|
|
||||||
var right = CheckExpression(expression.Right, left.Type);
|
var right = CheckExpression(expression.Right, left.Type);
|
||||||
|
if (right.Type != left.Type)
|
||||||
|
{
|
||||||
|
throw new TypeCheckerException(Diagnostic
|
||||||
|
.Error($"Expected type {left.Type} from left side of binary expression, but got {right.Type}")
|
||||||
|
.At(expression.Right)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
||||||
}
|
}
|
||||||
@@ -584,6 +648,13 @@ public sealed class TypeChecker
|
|||||||
}
|
}
|
||||||
|
|
||||||
var right = CheckExpression(expression.Right, left.Type);
|
var right = CheckExpression(expression.Right, left.Type);
|
||||||
|
if (right.Type != left.Type)
|
||||||
|
{
|
||||||
|
throw new TypeCheckerException(Diagnostic
|
||||||
|
.Error($"Expected type {left.Type} from left side of binary expression, but got {right.Type}")
|
||||||
|
.At(expression.Right)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,19 +339,15 @@ public class Generator
|
|||||||
BoolLiteralNode boolLiteralNode => boolLiteralNode.Value ? "true" : "false",
|
BoolLiteralNode boolLiteralNode => boolLiteralNode.Value ? "true" : "false",
|
||||||
ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode),
|
ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode),
|
||||||
ConstArrayInitializerNode constArrayInitializerNode => EmitConstArrayInitializer(constArrayInitializerNode),
|
ConstArrayInitializerNode constArrayInitializerNode => EmitConstArrayInitializer(constArrayInitializerNode),
|
||||||
ConstArrayToSliceNode constArrayToSliceNode => EmitConstArrayToSlice(constArrayToSliceNode),
|
|
||||||
ConvertCStringToStringNode convertCStringToStringNode => EmitConvertCStringToString(convertCStringToStringNode),
|
|
||||||
ConvertFloatNode convertFloatNode => EmitConvertFloat(convertFloatNode),
|
|
||||||
ConvertIntNode convertIntNode => EmitConvertInt(convertIntNode),
|
|
||||||
CStringLiteralNode cStringLiteralNode => $"\"{cStringLiteralNode.Value}\"",
|
CStringLiteralNode cStringLiteralNode => $"\"{cStringLiteralNode.Value}\"",
|
||||||
DereferenceNode dereferenceNode => EmitDereference(dereferenceNode),
|
DereferenceNode dereferenceNode => EmitDereference(dereferenceNode),
|
||||||
Float32LiteralNode float32LiteralNode => EmitFloat32Literal(float32LiteralNode),
|
Float32LiteralNode float32LiteralNode => EmitFloat32Literal(float32LiteralNode),
|
||||||
Float64LiteralNode float64LiteralNode => EmitFloat64Literal(float64LiteralNode),
|
Float64LiteralNode float64LiteralNode => EmitFloat64Literal(float64LiteralNode),
|
||||||
FloatToIntBuiltinNode floatToIntBuiltinNode => EmitFloatToIntBuiltin(floatToIntBuiltinNode),
|
CastNode castNode => EmitCast(castNode),
|
||||||
FuncCallNode funcCallNode => EmitFuncCall(funcCallNode),
|
FuncCallNode funcCallNode => EmitFuncCall(funcCallNode),
|
||||||
FuncIdentifierNode funcIdentifierNode => FuncName(funcIdentifierNode.Module, funcIdentifierNode.Name, funcIdentifierNode.ExternSymbol),
|
FuncIdentifierNode funcIdentifierNode => FuncName(funcIdentifierNode.Module, funcIdentifierNode.Name, funcIdentifierNode.ExternSymbol),
|
||||||
AddressOfNode addressOfNode => EmitAddressOf(addressOfNode),
|
AddressOfNode addressOfNode => EmitAddressOf(addressOfNode),
|
||||||
SizeBuiltinNode sizeBuiltinNode => $"sizeof({CType.Create(sizeBuiltinNode.TargetType)})",
|
SizeNode sizeBuiltinNode => $"sizeof({CType.Create(sizeBuiltinNode.TargetType)})",
|
||||||
SliceIndexAccessNode sliceIndexAccessNode => EmitSliceArrayIndexAccess(sliceIndexAccessNode),
|
SliceIndexAccessNode sliceIndexAccessNode => EmitSliceArrayIndexAccess(sliceIndexAccessNode),
|
||||||
StringLiteralNode stringLiteralNode => EmitStringLiteral(stringLiteralNode),
|
StringLiteralNode stringLiteralNode => EmitStringLiteral(stringLiteralNode),
|
||||||
StructFieldAccessNode structFieldAccessNode => EmitStructFieldAccess(structFieldAccessNode),
|
StructFieldAccessNode structFieldAccessNode => EmitStructFieldAccess(structFieldAccessNode),
|
||||||
@@ -442,46 +438,6 @@ public class Generator
|
|||||||
return $"({CType.Create(arrayType.ElementType)}[{arrayType.Size}]){{{string.Join(", ", values)}}}";
|
return $"({CType.Create(arrayType.ElementType)}[{arrayType.Size}]){{{string.Join(", ", values)}}}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitConstArrayToSlice(ConstArrayToSliceNode constArrayToSliceNode)
|
|
||||||
{
|
|
||||||
var arrayType = (NubConstArrayType)constArrayToSliceNode.Array.Type;
|
|
||||||
var array = EmitExpression(constArrayToSliceNode.Array);
|
|
||||||
return $"(slice){{.length = {arrayType.Size}, .data = (void*){array}}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EmitConvertCStringToString(ConvertCStringToStringNode convertCStringToStringNode)
|
|
||||||
{
|
|
||||||
var value = EmitExpression(convertCStringToStringNode.Value);
|
|
||||||
return $"(string){{.length = strlen({value}), .data = {value}}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EmitConvertFloat(ConvertFloatNode convertFloatNode)
|
|
||||||
{
|
|
||||||
var value = EmitExpression(convertFloatNode.Value);
|
|
||||||
var targetCast = convertFloatNode.TargetWidth switch
|
|
||||||
{
|
|
||||||
32 => "f32",
|
|
||||||
64 => "f64",
|
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
|
||||||
};
|
|
||||||
|
|
||||||
return $"({targetCast}){value}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EmitConvertInt(ConvertIntNode convertIntNode)
|
|
||||||
{
|
|
||||||
var value = EmitExpression(convertIntNode.Value);
|
|
||||||
var targetType = convertIntNode.TargetWidth switch
|
|
||||||
{
|
|
||||||
8 => convertIntNode.TargetSignedness ? "int8_t" : "uint8_t",
|
|
||||||
16 => convertIntNode.TargetSignedness ? "int16_t" : "uint16_t",
|
|
||||||
32 => convertIntNode.TargetSignedness ? "int32_t" : "uint32_t",
|
|
||||||
64 => convertIntNode.TargetSignedness ? "int64_t" : "uint64_t",
|
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
|
||||||
};
|
|
||||||
return $"({targetType}){value}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string EmitDereference(DereferenceNode dereferenceNode)
|
private string EmitDereference(DereferenceNode dereferenceNode)
|
||||||
{
|
{
|
||||||
var pointer = EmitExpression(dereferenceNode.Target);
|
var pointer = EmitExpression(dereferenceNode.Target);
|
||||||
@@ -510,18 +466,22 @@ public class Generator
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitFloatToIntBuiltin(FloatToIntBuiltinNode floatToIntBuiltinNode)
|
private string EmitCast(CastNode castNode)
|
||||||
{
|
{
|
||||||
var value = EmitExpression(floatToIntBuiltinNode.Value);
|
var value = EmitExpression(castNode.Value);
|
||||||
var targetType = floatToIntBuiltinNode.TargetType.Width switch
|
|
||||||
|
if (castNode is { Type: NubSliceType, Value.Type: NubConstArrayType arrayType })
|
||||||
{
|
{
|
||||||
8 => floatToIntBuiltinNode.TargetType.Signed ? "int8_t" : "uint8_t",
|
return $"(slice){{.length = {arrayType.Size}, .data = (void*){value}}}";
|
||||||
16 => floatToIntBuiltinNode.TargetType.Signed ? "int16_t" : "uint16_t",
|
}
|
||||||
32 => floatToIntBuiltinNode.TargetType.Signed ? "int32_t" : "uint32_t",
|
|
||||||
64 => floatToIntBuiltinNode.TargetType.Signed ? "int64_t" : "uint64_t",
|
// todo(nub31): Stop depending on libc
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
if (castNode is { Type: NubCStringType, Value.Type: NubStringType })
|
||||||
};
|
{
|
||||||
return $"({targetType}){value}";
|
return $"(string){{.length = strlen({value}), .data = {value}}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"({CType.Create(castNode.Type)}){value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitFuncCall(FuncCallNode funcCallNode)
|
private string EmitFuncCall(FuncCallNode funcCallNode)
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ public sealed class Parser
|
|||||||
{
|
{
|
||||||
var type = ParseType();
|
var type = ParseType();
|
||||||
ExpectSymbol(Symbol.CloseParen);
|
ExpectSymbol(Symbol.CloseParen);
|
||||||
return new SizeBuiltinSyntax(GetTokens(startIndex), type);
|
return new SizeSyntax(GetTokens(startIndex), type);
|
||||||
}
|
}
|
||||||
case "interpret":
|
case "interpret":
|
||||||
{
|
{
|
||||||
@@ -516,15 +516,13 @@ public sealed class Parser
|
|||||||
ExpectSymbol(Symbol.Comma);
|
ExpectSymbol(Symbol.Comma);
|
||||||
var expression = ParseExpression();
|
var expression = ParseExpression();
|
||||||
ExpectSymbol(Symbol.CloseParen);
|
ExpectSymbol(Symbol.CloseParen);
|
||||||
return new InterpretBuiltinSyntax(GetTokens(startIndex), type, expression);
|
return new InterpretSyntax(GetTokens(startIndex), type, expression);
|
||||||
}
|
}
|
||||||
case "floatToInt":
|
case "cast":
|
||||||
{
|
{
|
||||||
var type = ParseType();
|
|
||||||
ExpectSymbol(Symbol.Comma);
|
|
||||||
var expression = ParseExpression();
|
var expression = ParseExpression();
|
||||||
ExpectSymbol(Symbol.CloseParen);
|
ExpectSymbol(Symbol.CloseParen);
|
||||||
return new FloatToIntBuiltinSyntax(GetTokens(startIndex), type, expression);
|
return new CastSyntax(GetTokens(startIndex), expression);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -112,11 +112,11 @@ public record StructInitializerSyntax(List<Token> Tokens, TypeSyntax? StructType
|
|||||||
|
|
||||||
public record DereferenceSyntax(List<Token> Tokens, ExpressionSyntax Target) : ExpressionSyntax(Tokens);
|
public record DereferenceSyntax(List<Token> Tokens, ExpressionSyntax Target) : ExpressionSyntax(Tokens);
|
||||||
|
|
||||||
public record SizeBuiltinSyntax(List<Token> Tokens, TypeSyntax Type) : ExpressionSyntax(Tokens);
|
public record SizeSyntax(List<Token> Tokens, TypeSyntax Type) : ExpressionSyntax(Tokens);
|
||||||
|
|
||||||
public record InterpretBuiltinSyntax(List<Token> Tokens, TypeSyntax Type, ExpressionSyntax Target) : ExpressionSyntax(Tokens);
|
public record InterpretSyntax(List<Token> Tokens, TypeSyntax Type, ExpressionSyntax Target) : ExpressionSyntax(Tokens);
|
||||||
|
|
||||||
public record FloatToIntBuiltinSyntax(List<Token> Tokens, TypeSyntax Type, ExpressionSyntax Value) : ExpressionSyntax(Tokens);
|
public record CastSyntax(List<Token> Tokens, ExpressionSyntax Value) : ExpressionSyntax(Tokens);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ extern "main" func main(argc: i64, argv: [?]cstring): i64
|
|||||||
direction.y = -1
|
direction.y = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
x = x + @floatToInt(i32, direction.x * speed * raylib::GetFrameTime())
|
x = x + @cast(direction.x * speed * raylib::GetFrameTime())
|
||||||
y = y + @floatToInt(i32, direction.y * speed * raylib::GetFrameTime())
|
y = y + @cast(direction.y * speed * raylib::GetFrameTime())
|
||||||
|
|
||||||
raylib::BeginDrawing()
|
raylib::BeginDrawing()
|
||||||
{
|
{
|
||||||
|
|||||||
1
vscode-lsp/.gitignore
vendored
1
vscode-lsp/.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
out
|
out
|
||||||
|
nub-*.vsix
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { defineConfig } from '@vscode/test-cli';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
files: 'out/test/**/*.test.js',
|
|
||||||
});
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>generated c soruce</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<pre id="assembly">{{assembly}}</pre>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
4676
vscode-lsp/package-lock.json
generated
4676
vscode-lsp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
"name": "nub",
|
"name": "nub",
|
||||||
"displayName": "Nub Language Support",
|
"displayName": "Nub Language Support",
|
||||||
"description": "Language server client for nub lang",
|
"description": "Language server client for nub lang",
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"publisher": "nub31",
|
"publisher": "nub31",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -15,6 +15,12 @@
|
|||||||
"Programming Languages"
|
"Programming Languages"
|
||||||
],
|
],
|
||||||
"main": "./out/extension.js",
|
"main": "./out/extension.js",
|
||||||
|
"files": [
|
||||||
|
"out",
|
||||||
|
"server",
|
||||||
|
"syntaxes",
|
||||||
|
"language-configuration.json"
|
||||||
|
],
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"languages": [
|
"languages": [
|
||||||
{
|
{
|
||||||
@@ -31,31 +37,17 @@
|
|||||||
"scopeName": "source.nub",
|
"scopeName": "source.nub",
|
||||||
"path": "./syntaxes/nub.tmLanguage.json"
|
"path": "./syntaxes/nub.tmLanguage.json"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"commands": [
|
|
||||||
{
|
|
||||||
"command": "nub.openOutput",
|
|
||||||
"title": "Nub: Show Output",
|
|
||||||
"icon": "$(open-preview)"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"menus": {
|
|
||||||
"editor/title": [
|
|
||||||
{
|
|
||||||
"command": "nub.openOutput",
|
|
||||||
"when": "editorLangId == nub || resourceExtname == .nub",
|
|
||||||
"group": "navigation"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p ./",
|
"build": "esbuild src/extension.ts --bundle --platform=node --outfile=out/extension.js --external:vscode",
|
||||||
"watch": "tsc -watch -p ./"
|
"package": "vsce package"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "22.x",
|
"@types/node": "22.x",
|
||||||
"@types/vscode": "^1.105.0",
|
"@types/vscode": "^1.105.0",
|
||||||
|
"@vscode/vsce": "^3.6.2",
|
||||||
|
"esbuild": "^0.25.11",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { LanguageClient, TransportKind } from 'vscode-languageclient/node';
|
|||||||
|
|
||||||
let client: LanguageClient;
|
let client: LanguageClient;
|
||||||
|
|
||||||
export function activate(context: vscode.ExtensionContext) {
|
export async function activate(context: vscode.ExtensionContext) {
|
||||||
const serverExecutable = path.join(context.asAbsolutePath('server'), "nublsp");
|
const serverExecutable = path.join(context.asAbsolutePath('server'), "nublsp");
|
||||||
|
|
||||||
client = new LanguageClient(
|
client = new LanguageClient(
|
||||||
@@ -32,14 +32,6 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
client.onNotification("nub/output", (params: { path: string, content: string }) => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
vscode.commands.registerCommand('nub.openOutput', async () => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
client.start();
|
client.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user