added struct literals
This commit is contained in:
@@ -68,6 +68,12 @@ class LiteralFloat:
|
|||||||
value: float
|
value: float
|
||||||
type: TypeUsage
|
type: TypeUsage
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LiteralStruct:
|
||||||
|
name: str
|
||||||
|
fields: Dict[str, "Expression"]
|
||||||
|
type: TypeUsage
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FunctionCall:
|
class FunctionCall:
|
||||||
@@ -101,6 +107,7 @@ class Expression:
|
|||||||
expression: Union[
|
expression: Union[
|
||||||
LiteralInt,
|
LiteralInt,
|
||||||
LiteralFloat,
|
LiteralFloat,
|
||||||
|
LiteralStruct,
|
||||||
FunctionCall,
|
FunctionCall,
|
||||||
"Block",
|
"Block",
|
||||||
ReturnStatement,
|
ReturnStatement,
|
||||||
@@ -174,9 +181,12 @@ boring_grammar = r"""
|
|||||||
mult : "*"
|
mult : "*"
|
||||||
div : "/"
|
div : "/"
|
||||||
|
|
||||||
|
identifier : CNAME
|
||||||
literal_float : SIGNED_FLOAT
|
literal_float : SIGNED_FLOAT
|
||||||
literal_int : SIGNED_INT
|
literal_int : SIGNED_INT
|
||||||
identifier : CNAME
|
|
||||||
|
literal_struct_field : identifier ":" expression
|
||||||
|
literal_struct : identifier "{" (literal_struct_field ",")* "}"
|
||||||
|
|
||||||
function_call : expression "(" [expression ("," expression)*] ")"
|
function_call : expression "(" [expression ("," expression)*] ")"
|
||||||
|
|
||||||
@@ -199,6 +209,7 @@ boring_grammar = r"""
|
|||||||
|
|
||||||
term : literal_int
|
term : literal_int
|
||||||
| literal_float
|
| literal_float
|
||||||
|
| literal_struct
|
||||||
| variable_usage
|
| variable_usage
|
||||||
| function_call
|
| function_call
|
||||||
| "(" expression ")"
|
| "(" expression ")"
|
||||||
@@ -280,6 +291,15 @@ class TreeToBoring(Transformer):
|
|||||||
(f,) = f
|
(f,) = f
|
||||||
return LiteralFloat(value=float(f), type=UnknownTypeUsage())
|
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:
|
def identifier(self, i) -> str:
|
||||||
(i,) = i
|
(i,) = i
|
||||||
return str(i)
|
return str(i)
|
||||||
|
|||||||
@@ -224,6 +224,11 @@ class TypeChecker:
|
|||||||
if unify(ctx, subexpression, expression):
|
if unify(ctx, subexpression, expression):
|
||||||
changed = True
|
changed = True
|
||||||
return changed
|
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):
|
if isinstance(subexpression, parse.FunctionCall):
|
||||||
changed = self.with_function_call(ctx, subexpression)
|
changed = self.with_function_call(ctx, subexpression)
|
||||||
if unify(ctx, subexpression, expression):
|
if unify(ctx, subexpression, expression):
|
||||||
@@ -315,3 +320,18 @@ class TypeChecker:
|
|||||||
assert isinstance(literal_int.type, parse.DataTypeUsage)
|
assert isinstance(literal_int.type, parse.DataTypeUsage)
|
||||||
assert literal_int.type.name in ints, f"{literal_int.type}"
|
assert literal_int.type.name in ints, f"{literal_int.type}"
|
||||||
return False
|
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
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ fn unit_function() {
|
|||||||
let a: I32 = 4;
|
let a: I32 = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn returns_user(): User {
|
||||||
|
return User{
|
||||||
|
id: 4,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn main(): I32 {
|
fn main(): I32 {
|
||||||
add(4, subtract(5, 2))
|
add(4, subtract(5, 2))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user