22

I'm making a RAM Machine emulator in TypeScript, so I made an enum of the instruction types that a RAM can have:

enum InsType {
    LOAD,   // Put value from specified register (or literal) into accumulator.
    STORE,  // Store value from accumulator into specified register.
    READ,   // Read from input tape and write into specified register.
    WRITE,  // Write to output tape from specified register.
    ADD,    // Add value into accumulator.
    SUB,    // Subtract value from accumulator.
    MUL,    // Multiply accumulator by referenced (or literal) value.
    DIV,    // Divide accumulator by referenced (or literal) value.
    HALT,   // Stop program execution.
    JUMP,   // Jump unconditionally to line specified by tag.
    JZERO,  // Jump to line specified by tag if accumulator value is zero.
    JGTZ,   // Jump to line specified by tag if acc value is greater than zero.
}

I have to make sure each instruction has a valid operand type. My way of defining the valid operands is like this:

var valid_operands = {
  LOAD:   [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  STORE:  [                    OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  READ:   [                    OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  WRITE:  [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  ADD:    [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  SUB:    [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  MUL:    [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  DIV:    [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  HALT:   [OpType.NONE],
  JUMP:   [OpType.NAME],
  JZERO:  [OpType.NAME],
  JGTZ:   [OpType.NAME],
}

But I find that the TypeScript 'compiler' doesn't care what I put in the key values-- I can change LOAD: to LOADXYZ: and it won't bat an eye.

Also, when I try to change it to this:

var valid_operands = {
  InsType.LOAD:   [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  ...

It warns ':' expected at line XX col YY (those being the position of the .). I'm using the Atom TypeScript plugin to work, if it helps. Any help is appreciated.

Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80
JoseHdez_2
  • 4,040
  • 6
  • 27
  • 44

4 Answers4

17

define the object key inside the []

var valid_operands = {
  [InsType.LOAD]:   [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT],
  [InsType.STORE]:  [                    OpType.NUM_DIRECT, OpType.NUM_INDIRECT],

....

Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80
15

You can use Map.

enum InsType {
    LOAD,
    STORE
}

enum OpType {
    NUM_LITERAL
}

var vo2 = new Map<InsType, [OpType]>();
vo2.set(InsType.LOAD, [OpType.NUM_LITERAL]);
Zen
  • 5,065
  • 8
  • 29
  • 49
  • 1
    Thanks, that's also a valid answer. The way it differs from what I did is that it forces the key and value types, so it's better suited for writing strongly-typed programs. – JoseHdez_2 Jun 26 '16 at 18:51
  • There's still the small problem of strictness. You can add elements to Map after creation. – MTJ Dec 17 '17 at 19:57
13

You can use: key in Enum

export let MyHashMap: { [key in KeyType]: IMyObject }

sooo:

export enum KeyType {
    A = 'A',
    B = 'B'
}

export interface IMyObject {
    type: KeyType,
    title: string
}

export const MyObject: IMyObject[] = [
    { type: KeyType.A, title: 'my a' },
    { type: KeyType.B, title: 'my b' }
]

//this is the code you want
export let MyHashMap: { [key in KeyType]: IMyObject }


MyHashMap = MyObject.reduce((map, obj) => {
    map[obj.type] = obj;
    return map;
}, {} as { [key in KeyType]: IMyObject });
WhatIsHeDoing
  • 541
  • 1
  • 6
  • 20
8

The way I solved it was to assign each key-pair value individually.

var vo2 = { }

vo2[InsType.LOAD]  = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.STORE] = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.READ]  = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.WRITE] = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.ADD]   = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.SUB]   = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.MUL]   = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.DIV]   = [OpType.NUM_LITERAL, OpType.NUM_DIRECT, OpType.NUM_INDIRECT]
vo2[InsType.HALT]  = [OpType.NONE]
vo2[InsType.JUMP]  = [OpType.NAME]
vo2[InsType.JZERO] = [OpType.NAME]
vo2[InsType.JGTZ]  = [OpType.NAME]

It works fine. But if anyone finds a way to just declare a hash with enum keys, please go ahead and post an answer. :)

JoseHdez_2
  • 4,040
  • 6
  • 27
  • 44