121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
"""
|
|
Simple Query Processor for PySECONDO
|
|
|
|
Handles query execution and operator evaluation.
|
|
For simplicity, this is a basic implementation without full parsing.
|
|
"""
|
|
|
|
from typing import List, Any, Dict
|
|
from pysecondo.core.types import Type, BaseType, RelationType, TupleType, parse_type
|
|
from pysecondo.core.nested_list import NestedList
|
|
from pysecondo.algebras.base import AlgebraManager
|
|
from pysecondo.storage.memory import MemoryStorage
|
|
|
|
|
|
class QueryProcessor:
|
|
"""
|
|
Simple query processor
|
|
|
|
Handles:
|
|
- Object creation: create name : type
|
|
- Object updates: update name := value
|
|
- Operator evaluation: op(arg1, arg2, ...)
|
|
- Identifier lookup
|
|
"""
|
|
|
|
def __init__(self, algebra_manager: AlgebraManager, storage: MemoryStorage):
|
|
self.algebra_manager = algebra_manager
|
|
self.storage = storage
|
|
|
|
def execute_create(self, name: str, type_str: str) -> None:
|
|
"""
|
|
Execute: create name : type
|
|
|
|
Creates a new empty object with the specified type.
|
|
"""
|
|
obj_type = parse_type(type_str)
|
|
|
|
# Create empty value based on type
|
|
if isinstance(obj_type, RelationType):
|
|
# Empty relation
|
|
value = NestedList.list([])
|
|
elif isinstance(obj_type, TupleType):
|
|
# Empty tuple (invalid, but for error handling)
|
|
value = NestedList.list([])
|
|
else:
|
|
# For basic types, we create a default value
|
|
if obj_type == BaseType.INT:
|
|
value = NestedList.atom(0)
|
|
elif obj_type == BaseType.REAL:
|
|
value = NestedList.atom(0.0)
|
|
elif obj_type == BaseType.STRING:
|
|
value = NestedList.atom("")
|
|
elif obj_type == BaseType.BOOL:
|
|
value = NestedList.atom(False)
|
|
else:
|
|
raise ValueError(f"Unsupported type: {obj_type}")
|
|
|
|
self.storage.create_object(name, value, obj_type)
|
|
|
|
def execute_update(self, name: str, value: NestedList) -> None:
|
|
"""
|
|
Execute: update name := value
|
|
|
|
Updates an existing object with a new value.
|
|
"""
|
|
if not self.storage.object_exists(name):
|
|
raise ValueError(f"Object '{name}' does not exist")
|
|
|
|
obj_type = self.storage.get_type(name)
|
|
self.storage.update_object(name, value, obj_type)
|
|
|
|
def evaluate_operator(
|
|
self,
|
|
op_name: str,
|
|
args: List[NestedList],
|
|
arg_types: List[Type]
|
|
) -> NestedList:
|
|
"""
|
|
Evaluate an operator with given arguments
|
|
|
|
Args:
|
|
op_name: Operator name
|
|
args: Argument values
|
|
arg_types: Argument types
|
|
|
|
Returns:
|
|
Result of the operator
|
|
"""
|
|
operator = self.algebra_manager.get_operator(op_name)
|
|
|
|
if operator is None:
|
|
raise ValueError(f"Unknown operator: {op_name}")
|
|
|
|
# Type check
|
|
result_type = operator.type_map(arg_types)
|
|
|
|
# Execute operator
|
|
if operator.value_map is None:
|
|
raise ValueError(f"Operator {op_name} cannot be executed directly")
|
|
|
|
result = operator.value_map(args)
|
|
return result
|
|
|
|
def lookup_identifier(self, name: str) -> NestedList:
|
|
"""Look up an identifier in storage"""
|
|
value = self.storage.get_object(name)
|
|
|
|
if value is None:
|
|
raise ValueError(f"Unknown identifier: {name}")
|
|
|
|
return value
|
|
|
|
def get_identifier_type(self, name: str) -> Type:
|
|
"""Get type of an identifier"""
|
|
obj_type = self.storage.get_type(name)
|
|
|
|
if obj_type is None:
|
|
raise ValueError(f"Unknown identifier: {name}")
|
|
|
|
return obj_type
|