added support for floats
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
notes.txt
13
notes.txt
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user