Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,15 @@ add_library(bishop_lib
typechecker/maps.cpp
typechecker/pairs.cpp
typechecker/tuples.cpp
typechecker/deques.cpp
typechecker/stacks.cpp
typechecker/queues.cpp
typechecker/sets.cpp
typechecker/check_pair.cpp
typechecker/check_tuple.cpp
typechecker/check_deque.cpp
typechecker/check_stack.cpp
typechecker/check_queue.cpp
typechecker/check_priority_queue.cpp
typechecker/priority_queues.cpp
typechecker/check_map.cpp
Expand Down Expand Up @@ -131,6 +137,9 @@ add_library(bishop_lib
codegen/emit_string.cpp
codegen/emit_pair.cpp
codegen/emit_tuple.cpp
codegen/emit_deque.cpp
codegen/emit_stack.cpp
codegen/emit_queue.cpp
codegen/emit_priority_queue.cpp
codegen/emit_set.cpp
codegen/emit_method_call.cpp
Expand Down
113 changes: 113 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,118 @@ for i in 0..5 {
// sum is 15
```

## Deques

A double-ended queue that supports efficient insertion and removal from both ends.

### Deque Creation

```bishop
dq := Deque<int>(); // Empty deque
dq := Deque<str>(); // Empty string deque
```

### Deque Methods

| Method | Description |
|------------------|--------------------------------------|
| `push_front(T)` | Add element to front |
| `push_back(T)` | Add element to back |
| `pop_front()` | Remove and return front element |
| `pop_back()` | Remove and return back element |
| `front()` | Return front element without removing|
| `back()` | Return back element without removing |
| `get(int)` | Access element at index |
| `length()` | Return number of elements |
| `is_empty()` | Return true if deque is empty |
| `clear()` | Remove all elements |

### Deque Usage

```bishop
dq := Deque<int>();
dq.push_back(1); // [1]
dq.push_back(2); // [1, 2]
dq.push_front(0); // [0, 1, 2]

val := dq.pop_front(); // val = 0, dq = [1, 2]
val = dq.pop_back(); // val = 2, dq = [1]

print(dq.front()); // 1
print(dq.length()); // 1
```

## Stacks

A LIFO (Last-In-First-Out) stack data structure.

### Stack Creation

```bishop
s := Stack<int>(); // Empty stack
s := Stack<str>(); // Empty string stack
```

### Stack Methods

| Method | Description |
|---------------|-------------------------------------|
| `push(T)` | Push element onto top of stack |
| `pop()` | Remove and return top element (LIFO)|
| `top()` | Return top element without removing |
| `length()` | Return number of elements |
| `is_empty()` | Return true if stack is empty |

### Stack Usage (LIFO Order)

```bishop
s := Stack<int>();
s.push(1);
s.push(2);
s.push(3);

print(s.top()); // 3 (top element)
print(s.pop()); // 3 (removed, LIFO)
print(s.pop()); // 2
print(s.pop()); // 1
```

## Queues

A FIFO (First-In-First-Out) queue data structure.

### Queue Creation

```bishop
q := Queue<int>(); // Empty queue
q := Queue<str>(); // Empty string queue
```

### Queue Methods

| Method | Description |
|---------------|--------------------------------------|
| `push(T)` | Add element to back of queue |
| `pop()` | Remove and return front element (FIFO)|
| `front()` | Return front element without removing|
| `back()` | Return back element without removing |
| `length()` | Return number of elements |
| `is_empty()` | Return true if queue is empty |

### Queue Usage (FIFO Order)

```bishop
q := Queue<int>();
q.push(1);
q.push(2);
q.push(3);

print(q.front()); // 1 (first in)
print(q.pop()); // 1 (removed, FIFO)
print(q.pop()); // 2
print(q.pop()); // 3
```

## PriorityQueue

Priority queues maintain elements in priority order. By default, they are max heaps (highest value first).
Expand Down Expand Up @@ -908,6 +1020,7 @@ for n in nums {

**Note:** Set iteration order is not guaranteed.


## Error Handling

### Error Types
Expand Down
12 changes: 12 additions & 0 deletions codegen/codegen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ std::string emit_pair_field_access(const std::string& obj_str, const std::string
std::string emit_tuple_create(CodeGenState& state, const TupleCreate& tuple);
std::string emit_tuple_method_call(CodeGenState& state, const MethodCall& call, const std::string& obj_str, const std::vector<std::string>& args);

// Deque (emit_deque.cpp)
std::string emit_deque_create(const DequeCreate& deque);
std::string emit_deque_method_call(CodeGenState& state, const MethodCall& call, const std::string& obj_str, const std::vector<std::string>& args);

// Stack (emit_stack.cpp)
std::string emit_stack_create(const StackCreate& stack);
std::string emit_stack_method_call(CodeGenState& state, const MethodCall& call, const std::string& obj_str, const std::vector<std::string>& args);

// Queue (emit_queue.cpp)
std::string emit_queue_create(const QueueCreate& queue);
std::string emit_queue_method_call(CodeGenState& state, const MethodCall& call, const std::string& obj_str, const std::vector<std::string>& args);

// PriorityQueue (emit_priority_queue.cpp)
std::string emit_priority_queue_create(CodeGenState& state, const PriorityQueueCreate& pq);
std::string emit_priority_queue_method_call(CodeGenState& state, const MethodCall& call, const std::string& obj_str, const std::vector<std::string>& args);
Expand Down
77 changes: 77 additions & 0 deletions codegen/emit_deque.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* @file emit_deque.cpp
* @brief Deque emission for the Bishop code generator.
*/

#include "codegen.hpp"
#include <fmt/format.h>

using namespace std;

namespace codegen {

/**
* Emits a deque creation: Deque<T>() -> std::deque<T>{}.
*/
string emit_deque_create(const DequeCreate& deque) {
string cpp_type = map_type(deque.element_type);
return "std::deque<" + cpp_type + ">{}";
}

/**
* Emits a deque method call, mapping Bishop methods to std::deque equivalents.
*/
string emit_deque_method_call(CodeGenState& state, const MethodCall& call, const string& obj_str, const vector<string>& args) {
(void)state;

if (call.method_name == "length") {
return obj_str + ".size()";
}

if (call.method_name == "is_empty") {
return obj_str + ".empty()";
}

if (call.method_name == "push_front") {
return obj_str + ".push_front(" + args[0] + ")";
}

if (call.method_name == "push_back") {
return obj_str + ".push_back(" + args[0] + ")";
}

if (call.method_name == "pop_front") {
return fmt::format(
"[](auto& d) {{ auto tmp = d.front(); d.pop_front(); return tmp; }}({})",
obj_str
);
}

if (call.method_name == "pop_back") {
return fmt::format(
"[](auto& d) {{ auto tmp = d.back(); d.pop_back(); return tmp; }}({})",
obj_str
);
}

if (call.method_name == "front") {
return obj_str + ".front()";
}

if (call.method_name == "back") {
return obj_str + ".back()";
}

if (call.method_name == "get") {
return obj_str + ".at(" + args[0] + ")";
}

if (call.method_name == "clear") {
return obj_str + ".clear()";
}

// Unknown deque method - fall back to generic method call
return method_call(obj_str, call.method_name, args);
}

} // namespace codegen
12 changes: 12 additions & 0 deletions codegen/emit_expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ string emit(CodeGenState& state, const ASTNode& node) {
return emit_tuple_create(state, *tuple);
}

if (auto* deque = dynamic_cast<const DequeCreate*>(&node)) {
return emit_deque_create(*deque);
}

if (auto* stack = dynamic_cast<const StackCreate*>(&node)) {
return emit_stack_create(*stack);
}

if (auto* queue = dynamic_cast<const QueueCreate*>(&node)) {
return emit_queue_create(*queue);
}

if (auto* pq = dynamic_cast<const PriorityQueueCreate*>(&node)) {
return emit_priority_queue_create(state, *pq);
}
Expand Down
15 changes: 15 additions & 0 deletions codegen/emit_method_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ string emit_method_call(CodeGenState& state, const MethodCall& call) {
return emit_tuple_method_call(state, call, obj_str, args);
}

// Handle Deque methods
if (call.object_type.rfind("Deque<", 0) == 0) {
return emit_deque_method_call(state, call, obj_str, args);
}

// Handle Stack methods
if (call.object_type.rfind("Stack<", 0) == 0) {
return emit_stack_method_call(state, call, obj_str, args);
}

// Handle Queue methods
if (call.object_type.rfind("Queue<", 0) == 0) {
return emit_queue_method_call(state, call, obj_str, args);
}

// Handle PriorityQueue methods
if (call.object_type.rfind("PriorityQueue<", 0) == 0) {
return emit_priority_queue_method_call(state, call, obj_str, args);
Expand Down
58 changes: 58 additions & 0 deletions codegen/emit_queue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @file emit_queue.cpp
* @brief Queue emission for the Bishop code generator.
*/

#include "codegen.hpp"
#include <fmt/format.h>

using namespace std;

namespace codegen {

/**
* Emits a queue creation: Queue<T>() -> std::queue<T>{}.
*/
string emit_queue_create(const QueueCreate& queue) {
string cpp_type = map_type(queue.element_type);
return "std::queue<" + cpp_type + ">{}";
}

/**
* Emits a queue method call, mapping Bishop methods to std::queue equivalents.
*/
string emit_queue_method_call(CodeGenState& state, const MethodCall& call, const string& obj_str, const vector<string>& args) {
(void)state;

if (call.method_name == "length") {
return obj_str + ".size()";
}

if (call.method_name == "is_empty") {
return obj_str + ".empty()";
}

if (call.method_name == "push") {
return obj_str + ".push(" + args[0] + ")";
}

if (call.method_name == "pop") {
return fmt::format(
"[](auto& q) {{ auto tmp = q.front(); q.pop(); return tmp; }}({})",
obj_str
);
}

if (call.method_name == "front") {
return obj_str + ".front()";
}

if (call.method_name == "back") {
return obj_str + ".back()";
}

// Unknown queue method - fall back to generic method call
return method_call(obj_str, call.method_name, args);
}

} // namespace codegen
Loading