added struct literals

This commit is contained in:
Andrew Segavac
2021-06-12 10:59:58 -06:00
parent acbaf5f729
commit 421a5160fd
4 changed files with 48 additions and 2 deletions

View File

@@ -68,6 +68,12 @@ class LiteralFloat:
value: float
type: TypeUsage
@dataclass
class LiteralStruct:
name: str
fields: Dict[str, "Expression"]
type: TypeUsage
@dataclass
class FunctionCall:
@@ -101,6 +107,7 @@ class Expression:
expression: Union[
LiteralInt,
LiteralFloat,
LiteralStruct,
FunctionCall,
"Block",
ReturnStatement,
@@ -174,9 +181,12 @@ boring_grammar = r"""
mult : "*"
div : "/"
identifier : CNAME
literal_float : SIGNED_FLOAT
literal_int : SIGNED_INT
identifier : CNAME
literal_struct_field : identifier ":" expression
literal_struct : identifier "{" (literal_struct_field ",")* "}"
function_call : expression "(" [expression ("," expression)*] ")"
@@ -199,6 +209,7 @@ boring_grammar = r"""
term : literal_int
| literal_float
| literal_struct
| variable_usage
| function_call
| "(" expression ")"
@@ -280,6 +291,15 @@ class TreeToBoring(Transformer):
(f,) = f
return LiteralFloat(value=float(f), type=UnknownTypeUsage())
def literal_struct_field(self, lsf):
(name, expression) = lsf
return name, expression
def literal_struct(self, literal_struct) -> LiteralStruct:
name = literal_struct[0]
fields = {key: value for (key, value) in literal_struct[1:]}
return LiteralStruct(name=name, fields=fields, type=DataTypeUsage(name=name))
def identifier(self, i) -> str:
(i,) = i
return str(i)

View File

@@ -224,6 +224,11 @@ class TypeChecker:
if unify(ctx, subexpression, expression):
changed = True
return changed
if isinstance(subexpression, parse.LiteralStruct):
changed = self.with_literal_struct(ctx, subexpression)
if unify(ctx, subexpression, expression):
changed = True
return changed
if isinstance(subexpression, parse.FunctionCall):
changed = self.with_function_call(ctx, subexpression)
if unify(ctx, subexpression, expression):
@@ -315,3 +320,18 @@ class TypeChecker:
assert isinstance(literal_int.type, parse.DataTypeUsage)
assert literal_int.type.name in ints, f"{literal_int.type}"
return False
def with_literal_struct(self, ctx: Context, literal_struct: parse.LiteralStruct) -> bool:
assert literal_struct.name in ctx.environment
struct_declaration = ctx.environment[literal_struct.name]
assert isinstance(struct_declaration, parse.StructTypeDeclaration)
changed = False
for name, field_type in struct_declaration.fields.items():
assert name in literal_struct.fields
if self.with_expression(ctx, literal_struct.fields[name]):
changed = True
result_type, field_changed = type_compare(ctx, field_type, literal_struct.fields[name].type)
if field_changed:
literal_struct.fields[name].type = result_type
changed = True
return changed

View File

@@ -28,6 +28,12 @@ fn unit_function() {
let a: I32 = 4;
}
fn returns_user(): User {
return User{
id: 4,
};
}
fn main(): I32 {
add(4, subtract(5, 2))
}

View File

@@ -39,7 +39,7 @@ TODO:
* ~Normal assignment~
* Structs
* ~Define~
* Literal
* ~Literal~
* Getter
* Setter
* Generics