@@ -493,6 +493,17 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
493493 break ;
494494 }
495495
496+ case LLVMInstruction::Type::AppendToList: {
497+ assert (step.args .size () == 1 );
498+ const auto &arg = step.args [0 ];
499+ Compiler::StaticType type = optimizeRegisterType (arg.second );
500+ const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
501+ llvm::Value *itemPtr = m_builder.CreateCall (resolve_list_append_empty (), listPtr.ptr );
502+ createInitialValueStore (arg.second , itemPtr, type);
503+ // TODO: Implement list type prediction
504+ break ;
505+ }
506+
496507 case LLVMInstruction::Type::Yield:
497508 if (!m_warp) {
498509 freeHeap ();
@@ -962,6 +973,13 @@ void LLVMCodeBuilder::createListRemove(List *list)
962973 m_listPtrs[list] = LLVMListPtr ();
963974}
964975
976+ void LLVMCodeBuilder::createListAppend (List *list)
977+ {
978+ LLVMInstruction &ins = createOp (LLVMInstruction::Type::AppendToList, Compiler::StaticType::Void, Compiler::StaticType::Unknown, 1 );
979+ ins.workList = list;
980+ m_listPtrs[list] = LLVMListPtr ();
981+ }
982+
965983void LLVMCodeBuilder::beginIfStatement ()
966984{
967985 LLVMInstruction ins (LLVMInstruction::Type::BeginIf);
@@ -1519,6 +1537,41 @@ void LLVMCodeBuilder::createValueStore(LLVMRegisterPtr reg, llvm::Value *targetP
15191537 }
15201538}
15211539
1540+ void LLVMCodeBuilder::createInitialValueStore (LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType)
1541+ {
1542+ llvm::Value *converted = nullptr ;
1543+
1544+ if (sourceType != Compiler::StaticType::Unknown)
1545+ converted = castValue (reg, sourceType);
1546+
1547+ auto it = std::find_if (TYPE_MAP.begin (), TYPE_MAP.end (), [sourceType](const std::pair<ValueType, Compiler::StaticType> &pair) { return pair.second == sourceType; });
1548+ const ValueType mappedType = it == TYPE_MAP.cend () ? ValueType::Number : it->first ; // unknown type can be ignored
1549+
1550+ llvm::Value *valuePtr = m_builder.CreateStructGEP (m_valueDataType, targetPtr, 0 );
1551+ llvm::Value *typePtr = m_builder.CreateStructGEP (m_valueDataType, targetPtr, 1 );
1552+ m_builder.CreateStore (m_builder.getInt32 (static_cast <uint32_t >(mappedType)), typePtr);
1553+
1554+ switch (sourceType) {
1555+ case Compiler::StaticType::Number:
1556+ case Compiler::StaticType::Bool:
1557+ // Write number/bool directly
1558+ m_builder.CreateStore (converted, valuePtr);
1559+ break ;
1560+
1561+ case Compiler::StaticType::String:
1562+ m_builder.CreateCall (resolve_value_assign_cstring (), { targetPtr, converted });
1563+ break ;
1564+
1565+ case Compiler::StaticType::Unknown:
1566+ m_builder.CreateCall (resolve_value_assign_copy (), { targetPtr, reg->value });
1567+ break ;
1568+
1569+ default :
1570+ assert (false );
1571+ break ;
1572+ }
1573+ }
1574+
15221575void LLVMCodeBuilder::createValueCopy (llvm::Value *source, llvm::Value *target)
15231576{
15241577 // NOTE: This doesn't copy strings, but only the pointers
@@ -1864,6 +1917,12 @@ llvm::FunctionCallee LLVMCodeBuilder::resolve_list_remove()
18641917 return resolveFunction (" list_remove" , llvm::FunctionType::get (m_builder.getVoidTy (), { listPtr, m_builder.getInt64Ty () }, false ));
18651918}
18661919
1920+ llvm::FunctionCallee LLVMCodeBuilder::resolve_list_append_empty ()
1921+ {
1922+ llvm::Type *listPtr = llvm::PointerType::get (llvm::Type::getInt8Ty (m_ctx), 0 );
1923+ return resolveFunction (" list_append_empty" , llvm::FunctionType::get (m_valueDataType->getPointerTo (), { listPtr }, false ));
1924+ }
1925+
18671926llvm::FunctionCallee LLVMCodeBuilder::resolve_strcasecmp ()
18681927{
18691928 llvm::Type *pointerType = llvm::PointerType::get (llvm::Type::getInt8Ty (m_ctx), 0 );
0 commit comments