Skip to content

Commit

Permalink
add negative numbers support
Browse files Browse the repository at this point in the history
  • Loading branch information
ruskaof committed Dec 17, 2023
1 parent a58e319 commit 9e9139d
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 7 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Язык lisp-подобный.

Любое выражение в скобках (s-expression) возвращает значение.

Поддерживаются числовые и строковые литералы.

```bnf
program = s_expression
Expand Down Expand Up @@ -52,4 +52,10 @@ identifier = idenitfier_symbol | identifier_symbol identifier
idenitfier_symbol = letter | "_"
string_literal = "\"" *any symbol* "\""
```
```

## Организация памяти

После вычисления любого выражения, его результат кладется в аккумулятор.
При вычислении выражения с бинарным оператором, второй операнд вычисляется, кладется на стек,
после чего вычисляется перывый и проводится операция над ними с помощью адресации относительно стека.
18 changes: 14 additions & 4 deletions computer_simulator/machine/hardwire.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from computer_simulator.isa import Arg, ArgType, Instruction, Opcode

WORD_SIZE: int = 64
WORD_MAX_VALUE: int = 2**WORD_SIZE
WORD_MAX_VALUE: int = 2 ** (WORD_SIZE - 1) - 1
WORD_MIN_VALUE: int = -2 ** (WORD_SIZE - 1)


class UnknownSignalError(Exception):
Expand Down Expand Up @@ -127,12 +128,21 @@ def __init__(self) -> None:
def perform(self, op: AluOp, left: int, right: int) -> int:
handler = ALU_OP_HANDLERS[op]
value = handler(left, right)
value = self.handle_overflow(value)
self.set_flags(value)
return value

def set_flags(self, value) -> None:
self.flag_z = value == 0

@staticmethod
def handle_overflow(value: int) -> int:
if value >= WORD_MAX_VALUE:
return value - WORD_MAX_VALUE
if value <= WORD_MIN_VALUE:
return value + WORD_MAX_VALUE
return value


class DataPath:
def __init__(self, memory: list[Instruction | int], ports: dict[str, list[int]]) -> None:
Expand Down Expand Up @@ -309,9 +319,9 @@ def _need_address_fetch(instruction: Instruction) -> bool:

def _need_operand_fetch(instruction: Instruction) -> bool:
return (
instruction.arg is not None
and instruction.arg.arg_type in (ArgType.STACK_OFFSET, ArgType.INDIRECT, ArgType.ADDRESS)
and instruction.opcode not in NO_FETCH_OPERAND_INSTR
instruction.arg is not None
and instruction.arg.arg_type in (ArgType.STACK_OFFSET, ArgType.INDIRECT, ArgType.ADDRESS)
and instruction.opcode not in NO_FETCH_OPERAND_INSTR
)


Expand Down
1 change: 1 addition & 0 deletions computer_simulator/translator/expression_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def to_machine_code(self) -> str:

BINOP_OPCODE: dict[str, Opcode] = {
"+": Opcode.ADD,
"-": Opcode.SUB,
"=": Opcode.EQ,
"%": Opcode.MOD,
"/": Opcode.DIV,
Expand Down
2 changes: 1 addition & 1 deletion computer_simulator/translator/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def process_number_literal(tokens: list, idx: int, chars: str) -> int:
if idx >= len(chars):
return idx
start_idx = idx
while idx < len(chars) and chars[idx].isdigit():
while idx < len(chars) and (chars[idx].isdigit() or start_idx == idx and chars[idx] == "-"):
idx += 1
if idx > start_idx:
tokens.append(Token(Token.Type.INT, chars[start_idx:idx]))
Expand Down

0 comments on commit 9e9139d

Please sign in to comment.