Skip to content

Commit

Permalink
feat: Add core for type deducing
Browse files Browse the repository at this point in the history
  • Loading branch information
furesoft committed Jan 12, 2025
1 parent 555c0bb commit 94b15bd
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 75 deletions.
93 changes: 93 additions & 0 deletions NewSource/SocordiaC/Compilation/TypeDeducer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Collections.Immutable;
using DistIL.AsmIO;
using Socordia.CodeAnalysis.AST;
using Socordia.CodeAnalysis.AST.Expressions;
using Socordia.CodeAnalysis.AST.Literals;
using Socordia.CodeAnalysis.AST.TypeNames;

namespace SocordiaC.Compilation;

public static class TypeDeducer
{
public static readonly ImmutableDictionary<string, PrimType> TypenameTable = new Dictionary<string, PrimType>
{
["obj"] = PrimType.Object,
["none"] = PrimType.Void,
["bool"] = PrimType.Bool,
["u8"] = PrimType.Byte,
["u16"] = PrimType.UInt16,
["u32"] = PrimType.UInt32,
["u64"] = PrimType.UInt64,
["i8"] = PrimType.SByte,
["i16"] = PrimType.Int16,
["i32"] = PrimType.Int32,
["i64"] = PrimType.Int64,
["f32"] = PrimType.Single,
["f64"] = PrimType.Double,
["char"] = PrimType.Char,
["string"] = PrimType.String
}.ToImmutableDictionary();

public static TypeDesc? Deduce(AstNode node, ModuleResolver resolver)
{
if (node is SimpleTypeName simpleTypeName)
{
if (TypenameTable.TryGetValue(simpleTypeName.Name, out var deduce))
{
return deduce;
}
}

if (node is LiteralNode literal)
{
return resolver.Import(literal.Value.GetType());
}

if (node is UnaryOperatorExpression unary)
{
return DeduceUnary(unary, resolver);
}

if (node is TypeOfExpression)
{
return resolver.SysTypes.Type;
}

if (node is DefaultLiteral defaultLiteral)
{
return TypenameTable[defaultLiteral.Type!.ToString()];
}

node.AddError("Cannot deduce type");
return null;
}

private static TypeDesc? DeduceUnary(UnaryOperatorExpression unary, ModuleResolver resolver)
{
var left = Deduce(unary.Operand, resolver);

if (left.TryGetOperator(unary.Operator, out var opMethod, left))
{
return opMethod.ReturnType;
}

if (unary.Operator == "&")
{
return left.CreatePointer();
}
else if (unary.Operator == "*")
{
return left.ElemType;
}
else if (unary.Operator == "!")
{
return PrimType.Bool;
}
else if (unary.Operator == "-")
{
return left.ElemType;
}

return null;
}
}
79 changes: 4 additions & 75 deletions Source/Backlang.Driver/TypeDeducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,10 @@ namespace Backlang.Driver;

public static class TypeDeducer
{
public static readonly ImmutableDictionary<string, Symbol> TypenameTable = new Dictionary<string, Symbol>
{
["obj"] = CodeSymbols.Object,
["none"] = CodeSymbols.Void,
["bool"] = CodeSymbols.Bool,
["u8"] = CodeSymbols.UInt8,
["u16"] = CodeSymbols.UInt16,
["u32"] = CodeSymbols.UInt32,
["u64"] = CodeSymbols.UInt64,
["i8"] = CodeSymbols.Int8,
["i16"] = CodeSymbols.Int16,
["i32"] = CodeSymbols.Int32,
["i64"] = CodeSymbols.Int64,
["f16"] = Symbols.Float16,
["f32"] = Symbols.Float32,
["f64"] = Symbols.Float64,
["char"] = CodeSymbols.Char,
["string"] = CodeSymbols.String
}.ToImmutableDictionary();

//ToDo: check for implicit cast
public static IType Deduce(LNode node, Scope scope, CompilerContext context, QualifiedName modulename)
{
if (ImplementationStage.LiteralTypeMap.ContainsKey(node.Name))
{
return ImplementationStage.GetLiteralType(node, context, scope, modulename);
}

if (TypenameTable.ContainsKey(node.Name.Name))
{
return Deduce(LNode.Id(TypenameTable[node.Name.Name]), scope, context, modulename);
}

if (node.Calls(CodeSymbols.Typeof))
{
return Utils.ResolveType(context.Binder, typeof(Type));
}

{
if (node.Calls(Symbols.Unit) && node is var (_, value, unit))
{
return DeduceUnitType(scope, context, modulename, value, unit);
Expand All @@ -53,13 +19,6 @@ public static IType Deduce(LNode node, Scope scope, CompilerContext context, Qua
return Deduce(castType, scope, context, modulename);
}

if (node.ArgCount == 1 && node.Calls(CodeSymbols.Default))
{
if (node is var (_, (_, (_, type))))
{
return Deduce(type, scope, context, modulename);
}
}
else if (node.Calls(CodeSymbols.New))
{
if (node is var (_, call))
Expand All @@ -75,10 +34,7 @@ public static IType Deduce(LNode node, Scope scope, CompilerContext context, Qua
{
return DeduceArray(node, scope, context, modulename);
}
else if (node.ArgCount == 1 && node.Name.Name.StartsWith("'"))
{
return DeduceUnary(node, scope, context, modulename);
}

else if (node.ArgCount == 2 && node.Name.Name.StartsWith("'"))
{
return DeduceBinary(node, scope, context, modulename);
Expand Down Expand Up @@ -396,39 +352,12 @@ private static IType DeduceUnary(LNode node, Scope scope, CompilerContext contex
{
var left = Deduce(node.Args[0], scope, context, modulename);

if (left.TryGetOperator(node.Name.Name, out var opMethod, left))
{
return opMethod.ReturnParameter.Type;
}

if (node.Calls(CodeSymbols._AddressOf))
{
return left.MakePointerType(PointerKind.Transient);
}

if (node.Calls(CodeSymbols._Dereference))
{
if (left is PointerType pt)
{
return pt.ElementType;
}

context.AddError(node, "Cannot dereference non pointer type");
}
else if (node.Calls(CodeSymbols.Not))
{
ExpectType(node.Args[0], scope, context, modulename, context.Environment.Boolean);

return context.Environment.Boolean;
}

else if (node.Calls(CodeSymbols.NotBits))
{
return Deduce(node.Args[0], scope, context, modulename);
}
else if (node.Calls(CodeSymbols._Negate))
{
return NotExpectType(node.Args[0], scope, context, modulename, context.Environment.Boolean);
}


return null;
}
Expand Down

0 comments on commit 94b15bd

Please sign in to comment.