Coder Social home page Coder Social logo

markchenyutian / c0vm-ts Goto Github PK

View Code? Open in Web Editor NEW
6.0 2.0 2.0 42.01 MB

Compile, Debug and Visualize C0 Program on any modern browser!

Home Page: https://cs122.andrew.cmu.edu/visualc0/

TypeScript 91.46% JavaScript 5.49% HTML 0.57% CSS 2.47% C 0.01%
computer-science-education frontend-app visualization 15122 carnegie-mellon-university

c0vm-ts's Introduction

c0vm-ts's People

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

c0vm-ts's Issues

[Bug Report] Incorrect Variable Name

Describe the bug
The C0 -> BC0 compiler will reuse the elements in local variable array when possible. This means that a same element (index) in the local variable array may have different name and type during the runtime.

Specifically, suppose some variable x is declared in a scope and some other new variable y is declared after the scope x is in, the cc0 compiler will reuse the local variable array index for x previously to store value of y.

To Reproduce
Steps to reproduce the behavior:

  1. Compile the code below
  2. Set breakpoint on the line that contains int[] K = array_copy(...)
  3. Run the program
  4. In tabular debugger (and also graphical), the variable should have name J instead of i, which is already out of scope.

Expected behavior
As described above.

Screenshots

Code being executed

int[] array_copy(int[] A, int n)
//@requires n == \length(A);
//@ensures \length(\result) == n;
{
  int[] B = alloc_array(int, n);
  for (int i = 0; i < n; i ++) 
  //@loop_invariant 0 <= i;
  {
    B[i] = A[i];
  }
  return B;
}

int main() {
  int[] I = alloc_array(int, 3);
  for (int i = 0; i<3; i++) I[i] = i + 5;
  int[] J = array_copy(I, 3);
  int[] K = array_copy(J, 3);
  return 0;
}

Additional Context

(N/A)

-This bug is reported by Prof. Iliano

[Feature Request] Friendly Error Message on array index out of bound

Is your feature request related to a problem? Please describe.
Currently, the array index out-of-bound will generate some raw error message from the memory allocator, which is confusing for users.

Describe the solution you'd like
Wrap around the AADDS bytecode operator to capture out-of-bound error and translate into a more readable arrow (try to access index {...} in an array with length of {...})

Describe alternatives you've considered
N/A

Additional context
N/A

[Feature Request] When close last editor tab, create a new untitled empty tab instead

Is your feature request related to a problem? Please describe.

Currently, the visualizer does not allow to close the last tab. This is ok, but will pose additional layer of complexity on user operation.

Describe the solution you'd like

When close last editor tab, create a new untitled empty tab instead.

Describe alternatives you've considered

Additional context

[Feature Request] Add garbage collection sign to the released memory blocks

Is your feature request related to a problem? Please describe.

Not really, but in 15-122, student draw a Pacman-like icon near a memory block that is no longer accessible by the program to indicate that the block will be collected by the garbage collector. It would be nice if C0 visualizer can also follow this behavior / rule.

Describe the solution you'd like

When a memory block is no longer accessible for the program (detected by the BFS on heap as currently graphical debugger do), instead of hiding the memory block, show a "grey out" version of memory block floating around in the graphical debugger view.

  1. When student click on it, remove the node (garbage is collected).
  2. If the node is floated around for more than N (maybe configurable?) steps, delete the node automatically.

Describe alternatives you've considered

N/A

Additional context

This feature request is from prof. Iliano

[Bug Report] Step Does Not Validate Modified C0 File

Describe the bug
After Compile, if we modify the C0 File (even with an invalid one), Step would not raise an error. Step behaves as if the C0 File hasn't been modified. This is unexpected.

To Reproduce

C0VM.mp4

Expected behavior
Ideally, C0VM-ts should detect changes in C0 File before proceeding to Step.

Code being executed
The old C0 File:

int main() {
    int b = 1;
    int c = b + 1;
    return c;
}

The modified C0 File:

int main() {
    int b = 0;
    int main() {
        return b + 1;
    }
    return b;
}

[Feature Request] Flexible UI grid

Is your feature request related to a problem? Please describe.

It's a bit hard for the user on small-screen device (laptop with 1080p, for instance) to use this site since the debugger takes considerable amount of screen space and only <50% left for editor.

Describe the solution you'd like

Make the vertical boundary between components (Editor | Stdout+Debugger) draggable so user can determine the proportion of UI elements on screen freely.

Describe alternatives you've considered

N/A

Additional context

Feature request from prof. Iliano

[Feature] Replace breakpoint πŸ”΄ emoji into CSS-styled HTML Element

Is your feature request related to a problem? Please describe.
Currently the breakpoint is displayed differently on different platform since it is using emoji πŸ”΄ instead of HTML element with CSS style.

Such difference is not elegant and will cause confusion to users.

Describe the solution you'd like

Change the emoji πŸ”΄ into some real red circle or font awesome icons.

Describe alternatives you've considered
(N/A)

Additional context
(N/A)

[Feature] Shortcut key for Run/Step

Is your feature request related to a problem? Please describe.
According to our observation, many user will have rage click on "Step" button and it is not a very good user experience.

Describe the solution you'd like
We can add some shortcut key for run & step - for instance, maybe ctrl+shift+enter means "Run" and ctrl+enter means "Step"

Alternative Solution
We can also add an "Auto Step" button. When click on it, the C0VM will step in the code with certain interval (maybe 3-5sec?) until the user manually stops the auto step or C0VM meets a breakpoint.

However, the auto step feature will require us to add more complexity to the project - for instance, we need to allow our user to change the interval, start and pause the auto step.

Additional context
One thing to note is that we don't want these shortcut keys to conflict with the existing key bindings configured in editor.

[Bug Report] Not Compatible with WeChat Browser

Describe the bug
Application Crashed with WeChat Browser

To Reproduce
Steps to reproduce the behavior:

  1. Go to http://visualc0.tk/docs/ with WeChat Browser
  2. See the Error

Expected behavior
C0VM-ts should expectedly work on a variety of browsers.

Screenshots
image

Additional context

{
    "Version": "0.3.0",
    "ReactState": {
        "crashed": true,
        "dbgFullScreen": false,
        "settingMenuOn": false,
        "BC0SourceCode": "",
        "BC0BreakPoints": {},
        "TypedefRecord": {},
        "C0Editors": [
            {
                "title": "Untitled_0.c0",
                "key": 0,
                "content": ""
            }
        ],
        "ActiveEditor": 0,
        "C0BreakPoint": {},
        "PrintoutValue": "",
        "C0Running": false,
        "CompilerFlags": {
            "d": false
        }
    },
    "ReactContext": {
        "mode": "full-page",
        "std_out": true,
        "debug_console": true,
        "c0_only": true
    },
    "GlobalState": {
        "configuration": {
            "DEBUG": true,
            "DEBUG_DUMP_MEM": false,
            "DEBUG_DUMP_STEP": false,
            "MEM_POOL_SIZE": 51200
        }
    }
}

[Feature] Import C0 source code Folder (C0 Project)

Is your feature request related to a problem? Please describe.
Currently we can only import one file at a time. It takes a lot of repetitive work to import all the files in a C0 project.

Describe the solution you'd like
Add an import folder feature when the editor is blank, which will automatically import all the files in folder.

Describe alternatives you've considered
(Empty)

Additional context
Will be nice to put an upper limit (Maybe 20) for the number of files that can be imported at a time and prompt error if more than 20 files are in the selected folder.

Better Graph Layout Algorithm

Currently, the graph layout in graphical visualizer (graph mode of debug console) is calculated by a naive BFS search on heap memory

  1. Whenever a new level of graph is being drawn, increment the x-coordinate of "pen" to a fixed size.
  2. When rendering a node, use function in ./components/debug_console/graphical_utility.ts to calculate the node height and increment y-coordinate by that size.

However, there are some specific JS/TS libraries that focus on graph layout generating, for example:

Maybe we can use one of these to replace the naive algorithm that is currently used to provide a better experience.

[Bug Report] Editor Tab Name not updated properly

Describe the bug
When importing the file, the editor tab name is not set to imported file's name.

To Reproduce
Steps to reproduce the behavior:

  1. Import a C0 file into the editor using "Load File" button
  2. Notice that the editor tab name is still Untitled_0.c0
  3. Switch to BC0 editor
  4. Switch back to C0 editor, and the name is now rendered correctly

Expected behavior
The displayed editor tab name is updated correctly when the file is imported.

Screenshots
(N/A)

Code being executed
(N/A)

Additional context
I suspect this is related to the recent update of editor tab rename feature (PR #28 ).

[Feature] Using the compile command provided in README.txt

Is your feature request related to a problem? Please describe.

Though mentioned in the tutorial page, students tend to be confused by the concept that order of editor tabs is the order of file names send to compiler.

In 15-122 course project / homework, the codebase mostly comes with a README.txt file which includes some command lines showing how to compile the project. Usually in form of

    % cc0 a.c0 b.c0 -W -d

If the visualizer can detect this file sequence and apply the recommended compile order automatically, it will be easier to use and we won't need to rearrange the tabs manually in a large project.

Describe the solution you'd like

Add an editor tab that shows the README.txt file. If a line is a valid cc0 compiler command in form mentioned above, record the file sequence and apply the sequence when possible.

If the provided command is not possible (e.g. missing files in C0VM.ts), or no such command is found, then fallback to use the editor tab order.

Additional context
Requested by prof. Iliano

Running factorial gives error [Bug Report]

I tried importing fact.bc0 into the editor. It gives me a getBigUint64 error. I'm working on a MacBook Pro, 2020 M1 running MacOS BigSur, through Safari.

Steps to reproduce the behavior:

  1. Go to BC0 editor.
  2. Load Manually fact.bc0, can be found/produced from C0VM assignment
  3. Click Run. See error.

Expected behavior
I believe that it should work, and start running the byte code.

Screen Recording 2022-08-22 at 6.17.02 PM.mov.zip

Unexpected type error when dereferencing Null pointer

Describe the bug
Unexpected type error when dereferencing Null pointer

To Reproduce
Steps to reproduce the behavior:

  1. Initialize a pointer to Null.
  2. Try dereference the pointer.
  3. See error

Expected behavior
Expect to report memory error

Screenshots
Screen Shot 2022-12-28 at 4 29 28 PM

[Bug Report] Breakpoints are missing when switching between C0 and BC0 mode of the editor

Describe the bug
When switching the mode of editor (C0 / BC0), the existing breakpoints in editor will be discarded.

To Reproduce
Steps to reproduce the behavior:

  1. Import some arbitrary C0 source code file
  2. Set some breakpoints in the C0 editor
  3. Switch the editor into BC0 mode
  4. Switch back the editor into C0 mode
  5. The breakpoints set in step 2 are lost

Expected behavior
The breakpoints should be preserved after switching modes

Screenshots
(N/A)

Code being executed
(N/A)

Additional context
Maybe we can use the toJSON and fromJSON method in CodeMirror to store the state.

[Feature Request] Highlight the editor tab where execution is happening right now

Is your feature request related to a problem? Please describe.

Currently only the line that is executing will be highlighted. Under the situation where multiple-files are included in a single project, it's some time hard to find where the current position of visualizer is.

Describe the solution you'd like

Highlight the tab visualizer is currently on.

Describe alternatives you've considered

Add a "jump to current line" button somewhere in the UI

Additional context

Feature requested by prof. Iliano

Remove StructuredClone dependency

StructuredClone is poorly supported by browser (Chrome started to support this API only since Jan 2022).

Lack of support for this function will make the application crash completely as in issue #6 . Similar behavior is also seen on older version of chrome, etc.

Since this function is not related with core functionality of application, it is possible to remove dependency to this API. This will significantly improve the compatibility of this app.

[Bug Report] Memory Diagram not showing edges properly

Describe the bug

Occasionally, the memory diagram view of Debug Console does not render the edges in memory diagram. The nodes and handles on node are rendered correctly but the edge disappear.

⚠️ Notes

  1. This bug might be related with third-party library ReactFlow we used for rendering flow graph
  2. This bug might be related with browser compatibility, there are reports showing that this bug does not exist on FireFox.

To Reproduce
Steps to reproduce the behavior:

  1. Compile the following code
#use <conio>
#use <util>
#use <string>

struct mess{
    char* u;
    int*  w;
    int**  x;
    int** y;
    int[] z;
};
typedef struct mess* mess_t;

int main() {
    int n = 4;
    int *a = alloc(int);
    int *b = alloc(int);
    int *c = alloc(int);
    int[] d = alloc_array(int, n);
    int **e = alloc(int*);
    mess_t m = alloc(struct mess);
    *a = 4;
    *b = n * (*c);
    *c = n + d[0];
    d[0] = n;
    d[1] = *b;
    m->x = e;
    *m->x = b;
    m->y = e;
    *(*m->y) = *a;
    m->w = a;
    m->z = d;
    return 1;
}
  1. Switch the debug view to graphical view
  2. Execute to the line m -> x = e;
  3. The pointer between struct m and e does not show on the graphical debug console.

Expected behavior

An edge should exist between m.x and e.

Screenshots

image

Code being executed

As shown above

Additional context

This problem might be related with xyflow/xyflow#3171

[Feature] Hide detailed data structure from object files in debugger (can turn on/off)

Is your feature request related to a problem? Please describe.

In 15-122, students are assumed to treat library provided data structures as a black box and should not learn the actual data structure used by the library. However, the C0Visualizer is not respecting this "opacity rule" in debug console.

Describe the solution you'd like

Instead of showing the actual node / expandable value for the provided data structure, show a "...hidden..." (or something similar) to the abstract data structure provided by the library.

Describe alternatives you've considered

N/A

Additional context

This feature request is from prof. Iliano

Type Inference with recursive function [Bug Report]

Describe the bug
C0VM failed to inference type information during runtime when there is a recursive function in the program.

To Reproduce
Run the C0 code below BC0 attached here:

C0 C0 FF EE       # magic number
00 17             # version 11, arch = 1 (64 bits)

00 00             # int pool count
# int pool

00 00             # string pool total size
# string pool

00 03             # function count
# function_pool

#<main>
00                # number of arguments = 0
02                # number of local variables = 2
00 0E             # code length = 14 bytes
10 00    # bipush 0           # 0
36 00    # vstore 0           # cnt = 0;
10 01    # bipush 1           # 1
B8 00 02 # invokestatic 2     # buildHaoTree(1)
36 01    # vstore 1           # tree = buildHaoTree(1);
10 00    # bipush 0           # 0
B0       # return             # 


#<buildTree>
01                # number of arguments = 1
02                # number of local variables = 2
00 1A             # code length = 26 bytes
BB 18    # new 24             # alloc(struct tree)
36 01    # vstore 1           # tmp = alloc(struct tree);
15 01    # vload 1            # tmp
62 00    # aaddf 0            # &tmp->left
01       # aconst_null        # NULL
4F       # amstore            # tmp->left = NULL;
15 01    # vload 1            # tmp
62 08    # aaddf 8            # &tmp->right
01       # aconst_null        # NULL
4F       # amstore            # tmp->right = NULL;
15 01    # vload 1            # tmp
62 10    # aaddf 16           # &tmp->val
15 00    # vload 0            # val
4E       # imstore            # tmp->val = val;
15 01    # vload 1            # tmp
B0       # return             # 


#<buildHaoTree>
01                # number of arguments = 1
02                # number of local variables = 2
00 3A             # code length = 58 bytes
15 00    # vload 0            # cnt
10 0A    # bipush 10          # 10
A3 00 06 # if_icmpgt +6       # if (cnt > 10) goto <00:then>
A7 00 08 # goto +8            # goto <01:else>
# <00:then>
01       # aconst_null        # NULL
B0       # return             # 
A7 00 2E # goto +46           # goto <02:endif>
# <01:else>
BB 18    # new 24             # alloc(struct tree)
36 01    # vstore 1           # tmp = alloc(struct tree);
15 01    # vload 1            # tmp
62 00    # aaddf 0            # &tmp->left
10 02    # bipush 2           # 2
15 00    # vload 0            # cnt
68       # imul               # (2 * cnt)
B8 00 02 # invokestatic 2     # buildHaoTree((2 * cnt))
4F       # amstore            # tmp->left = buildHaoTree((2 * cnt));
15 01    # vload 1            # tmp
62 08    # aaddf 8            # &tmp->right
10 02    # bipush 2           # 2
15 00    # vload 0            # cnt
68       # imul               # (2 * cnt)
10 01    # bipush 1           # 1
60       # iadd               # ((2 * cnt) + 1)
B8 00 02 # invokestatic 2     # buildHaoTree(((2 * cnt) + 1))
4F       # amstore            # tmp->right = buildHaoTree(((2 * cnt) + 1));
15 01    # vload 1            # tmp
62 10    # aaddf 16           # &tmp->val
15 00    # vload 0            # cnt
4E       # imstore            # tmp->val = cnt;
15 01    # vload 1            # tmp
B0       # return             # 
# <02:endif>

00 00             # native count
# native pool


Expected behavior
Graph & Table Visualizer show the recursive tree correctly.

Screenshots
image

Code being executed

struct tree{
  struct tree *left;
  struct tree *right;
  int val;
};

typedef struct tree tree_t;

tree_t *buildTree(int val)
//@ensures \result != NULL;
{
    tree_t *tmp = alloc(tree_t);
    tmp->left = NULL;
    tmp->right = NULL;
    tmp->val = val;
    return tmp;
}

tree_t *buildHaoTree(int cnt){
    if(cnt > 10){
        return NULL;
    }
    else{
        tree_t *tmp = alloc(tree_t);
        tmp->left = buildHaoTree(2 * cnt);
        tmp->right = buildHaoTree(2 * cnt + 1);
        tmp->val = cnt;
        return tmp;
    }
}

int main(){
    int cnt = 0;
    tree_t *tree = buildHaoTree(1);
    return 0;
}

Additional context
Add any other context about the problem here.

Display Operand Stack [Feature]

Description
Opcode actions like bipush, add, sub, etc manipulate the operand stack. It would be cool to have a visual in mode and/or

mode to display this, in addition to the function call stack you already have.

Screen Shot 2022-08-22 at 6 36 38 PM

So for example in the situation above, we would have n in the operand stack, and then after executing that line, 1 would be added.

Struct fields don't appear until assignment

Describe the bug

Struct fields aren't shown until they're assigned to, but should be shown immediately with the default value.

To Reproduce

Here's an example program to display the issue:

struct Y {
    int* val;
    struct Y* next;
};

struct X {
    int* p;
    char[] cs;
    struct Y* y;
};

int main() {
    struct X* a = alloc(struct X);
    a->p = alloc(int);
    *(a->p) = 15122;
    a->cs = alloc_array(char, 3);
    a->cs[0] = 'a';
    a->cs[1] = 'b';
    a->cs[2] = 'c';
    
    struct Y* b = alloc(struct Y); 
    a->y = b;
    a->y->val = a->p;
    b->next = a->y;
    return 0;
}

The issue can be seen at, e.g., lines 16/17.

Expected behavior
Structs should be shown in full at time of allocation, with default values for each field.

[Bug Report] VM Step does not abort when dereference null pointer

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Put in the code attached below.
  2. Press "step" button. The code can be "executed" without error raised / abort.

Expected behavior

  1. When executing line 12 (int* e = *(d->a);), Dereference NULL Pointer exception should be raised and the VM should abort.

Screenshots

image

Code being executed

struct abc{
    int** a;
    int b;
    char* c;
};

typedef struct abc abc_t;

int main()
{
    abc_t* d = alloc(struct abc);
    int* e = *(d->a);
    d->a = alloc(int*);
    *(d->a) = alloc(int);
    **(d->a) = 5;
   
    *(d->c) = 'c';
    d->a = alloc(int*);

    //draw the memory diagram as it is on this line
    //make sure to mark any garbage colleted memory with a "pacman"

    return 1;
}

Additional context
N/A

Nested structs are not well supported

Describe the bug

Nested structs should have the same level of support as other fields, but are currently displayed just as nameless offsets, or result in a crash.

To Reproduce
See attached code.

Expected behavior
Structs should be displayed the same as all other fields, and valid code should not crash

Screenshots
If applicable, add screenshots to help explain your problem.

Code being executed

Struct containing a struct
struct X { int x; };

struct Y {
    int foo;
    struct X x;
};

int main() {
    struct Y* a = alloc(struct Y);
    a->foo = 1;
    a->x.x = 2;
    return 0;
}
Array of structs
struct X { int x; };

struct Y {
    int foo;
    struct X x;
};

int main() {
    struct Y[] a = alloc_array(struct Y, 10);
    a[0].foo = 3;
    a[0].x.x = 0;
    a[1].foo = 5;
    return 0;
}

Additional context
Not super high prio, but the crashing is not good.

Rename tab not intuitive (UI improvement)

I couldn't figure out how to rename a tab without searching through the documentation. alt + left click is probably not something people think of.

Maybe double click or right click menu with rename option would be more intuitive.

[Feature] Friendly Error Message

Update the error handler so that error message is easier to interpret and more informative

  1. Print the c0 line number if possible
  2. Error message of "Dereference NULL" instead of "try to perform +n on address 0 where allocated block size is 0"
  3. Print the exact native function that is not supported by C0VM.ts
  4. Friendly message about array index out of bound
  5. [optional] Colored text in stdout window?

[Bug Report] parse_ints function not working as expected in native libraray parse

Describe the bug
The parse_ints function in <parse> library does not work as expected.

To Reproduce
Steps to reproduce the behavior:

  1. Execute code
     #use <parse>
     
     int main() {
         int[] A = parse_ints("11111", 10);
         return 0;
     }
  2. Put breakpoint on return 0 and run the program

Expected behavior
See A = [11111] in debug console.

Screenshots
image

Code being executed
As described above

Additional context
The result is non-deterministic (?), the output varies from machine to machine.

[Feature Request] Support wildcard matching in README.txt while importing 122 Project

Is your feature request related to a problem? Please describe.

In the standard format of 15-122 project, the README.txt may contain lines like o0/* to include all files in directory o0. However, current implementation of project loader does not support such syntax. This might lead to unexpected load failure when the student is trying to use project file loader.

Describe the solution you'd like

The project loader can identify the wildcard matching character * in the README.txt and import files automatically following the semantic of project description file.

Describe alternatives you've considered

Additional context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.