나는 간단한 컴파일러를 개발 중이며 적절한 방식으로 자동 유형 변환을 구현하려고합니다. 내가 가지고있는 타입은 byte, int, uint16_t, uint64_t, int16_t, float, double 등입니다. 컴파일러는 타입을 체크하고, 어떤 타입의 값이 다른 타입으로 사용될 수 있는지를 결정해야합니다.컴파일러의 기본 유형에 대한 자동 유형 변환을위한 좋은 알고리즘은 무엇입니까?
예를 들어, int16_t 값은 정밀도가 손실되지 않으므로 int32_t 값으로 문제없이 사용할 수 있습니다. int16_t가 예상되는 곳에 int32_t 값을 사용하면 경고 또는 오류가 발생합니다.
내가 지금까지 가지고있는 코드는 다음
def do_coerce(self, expr, typ):
""" Try to convert expression into the given type.
expr: the expression value with a certain type
typ: the type that it must be
Raises an error is the conversion cannot be done.
"""
if self.context.equal_types(expr.typ, typ):
# no cast required
pass
elif isinstance(expr.typ, ast.PointerType) and \
isinstance(typ, ast.PointerType):
# Pointers are pointers, no matter the pointed data.
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('int', expr.typ) and \
isinstance(typ, ast.PointerType):
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('int', expr.typ) and \
self.context.equal_types('byte', typ):
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('int', expr.typ) and \
self.context.equal_types('float', typ):
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('int', expr.typ) and \
self.context.equal_types('double', typ):
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('double', expr.typ) and \
self.context.equal_types('float', typ):
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('float', expr.typ) and \
self.context.equal_types('double', typ):
expr = ast.TypeCast(typ, expr, expr.loc)
elif self.context.equal_types('byte', expr.typ) and \
self.context.equal_types('int', typ):
expr = ast.TypeCast(typ, expr, expr.loc)
else:
raise SemanticError(
"Cannot use '{}' as '{}'".format(expr.typ, typ), expr.loc)
self.check_expr(expr)
return expr
어떤이 코드가 수행하는 것은 '소스'유형과 '대상'유형을 확인하고, 이러한 특정 유형의 경우, 다음을 자동 형변환이면 오류가 발생합니다. 코드는 작동하지만 형식의 변형을 추가하려고합니다.이 if-else 트리가 매우 커질 것입니다.
나는 좋은 해결책을 찾아 봤는데 clang, gcc 및 C# 컴파일러의 소스 코드를 읽으려고했지만이 문제를 해결하는 소스 코드를 찾을 수 없었다.
이 문제를 해결하는 방법에 대한 아이디어가 있습니까? 아니면 이것이 구현 된 소스에 대한 포인터가 있습니까?
쿨! 팁 고마워! – Windel