added support for floats

This commit is contained in:
Andrew Segavac
2021-05-29 10:50:15 -06:00
parent b8769f43e3
commit 374e080f26
4 changed files with 46 additions and 12 deletions

View File

@@ -62,6 +62,12 @@ class LiteralInt:
type: TypeUsage type: TypeUsage
@dataclass
class LiteralFloat:
value: float
type: TypeUsage
@dataclass @dataclass
class FunctionCall: class FunctionCall:
source: "Expression" source: "Expression"
@@ -85,7 +91,7 @@ class VariableUsage:
@dataclass @dataclass
class Expression: class Expression:
expression: Union[LiteralInt, FunctionCall, VariableUsage, Operation] expression: Union[LiteralInt, LiteralFloat, FunctionCall, VariableUsage, Operation]
type: TypeUsage type: TypeUsage
@@ -131,8 +137,9 @@ boring_grammar = r"""
mult : "*" mult : "*"
div : "/" div : "/"
literal_int: SIGNED_NUMBER literal_float : SIGNED_FLOAT
identifier : NAME literal_int : SIGNED_INT
identifier : CNAME
function_call : expression "(" [expression ("," expression)*] ")" function_call : expression "(" [expression ("," expression)*] ")"
@@ -152,6 +159,7 @@ boring_grammar = r"""
| term | term
term : literal_int term : literal_int
| literal_float
| variable_usage | variable_usage
| function_call | function_call
| "(" expression ")" | "(" expression ")"
@@ -185,8 +193,9 @@ boring_grammar = r"""
module : (function)* module : (function)*
%import common.CNAME -> NAME %import common.CNAME
%import common.SIGNED_NUMBER %import common.SIGNED_INT
%import common.SIGNED_FLOAT
%import common.WS %import common.WS
%ignore WS %ignore WS
""" """
@@ -214,6 +223,10 @@ class TreeToBoring(Transformer):
(n,) = n (n,) = n
return LiteralInt(value=int(n), type=UnknownTypeUsage()) return LiteralInt(value=int(n), type=UnknownTypeUsage())
def literal_float(self, f) -> LiteralFloat:
(f,) = f
return LiteralFloat(value=float(f), type=UnknownTypeUsage())
def identifier(self, i) -> str: def identifier(self, i) -> str:
(i,) = i (i,) = i
return str(i) return str(i)

View File

@@ -131,6 +131,10 @@ class TypeChecker:
if self.with_literal_int(env, type_env, subexpression): if self.with_literal_int(env, type_env, subexpression):
changed = True changed = True
return changed return changed
if isinstance(subexpression, parse.LiteralFloat):
if self.with_literal_float(env, type_env, subexpression):
changed = True
return changed
if isinstance(subexpression, parse.FunctionCall): if isinstance(subexpression, parse.FunctionCall):
if self.with_function_call(env, type_env, subexpression): if self.with_function_call(env, type_env, subexpression):
changed = True changed = True
@@ -198,11 +202,14 @@ class TypeChecker:
changed = True changed = True
return changed return changed
def with_literal_int(self, env: Environment, type_env: TypeEnvironment, literal_int: parse.LiteralInt) -> bool: def with_literal_float(self, env: Environment, type_env: TypeEnvironment, literal_float: parse.LiteralFloat) -> bool:
ints = [ floats = ["F32", "F64", "F128"]
parse.DataTypeUsage(name=name) if not isinstance(literal_float.type, parse.UnknownTypeUsage):
for name in ["I8", "I16", "I32", "I64", "I128"] assert literal_float.type.name in floats, f"{literal_float.type}"
] return False
if not isinstance(literal_int.type, parse.UnknownTypeUsage):
assert literal_int.type in ints, f"{literal_int.type}" def with_literal_int(self, env: Environment, type_env: TypeEnvironment, literal_int: parse.LiteralInt) -> bool:
ints = ["I8", "I16", "I32", "I64", "I128", "U8", "U16", "U32", "U64", "U128"]
if not isinstance(literal_int.type, parse.UnknownTypeUsage):
assert literal_int.type.name in ints, f"{literal_int.type}"
return False return False

View File

@@ -1,5 +1,6 @@
fn add(a: I32, b: I32): I32 { fn add(a: I32, b: I32): I32 {
let foo = 4; let foo = 4;
let test_float: F32 = 10.2;
a + b + foo a + b + foo
} }

View File

@@ -26,3 +26,16 @@ class TypeUsage:
result: Identifier # Result of useage - either is the type, or is the return value if it's a function result: Identifier # Result of useage - either is the type, or is the return value if it's a function
type_args: List[Type] # Generics type_args: List[Type] # Generics
arguments: Optional[List[Type]] # Specified if it is a function, this is how you tell if it's a function arguments: Optional[List[Type]] # Specified if it is a function, this is how you tell if it's a function
TODO:
* ~Float Literals~
* Block expression
* Return keyword
* Structs
* Generics
* Enums
* Methods
* Traits
* Async