2 kyu

Assembler interpreter (part II)

1,029 of 2,757ShinuToki
Description
Loading description...
Interpreters
Refactoring
  • Please sign in or sign up to leave a comment.
  • adnan.ha Avatar

    This exercise has a good concept, but several aspects could be improved. First, the specification of function returns is unclear, which can lead to confusion, especially when dealing with recursive calls. Additionally, jump instructions and labels need more details, such as what to do if a label is undefined. There’s also a lack of proper validation for instruction parameters and error management. It would be helpful if the prompt provided more details on handling spaces, comments in the code, and how to properly concatenate values in the msg instruction.

  • Jordann0 Avatar

    why this fail,it expect -1 but it doesn't jump to exit function since both not equal

    mov i, 2 ; instruction mov i, 2 mov q, 12 ; instruction mov q, 12 call func msg 'Random result: ', n end

    func: cmp i, q je exit mov n, i sub n, q ret ; Do nothing exit: msg 'Do nothing'

  • GreatGonzales92 Avatar

    C# tests seem to be timing out on correct answer. Adding " " to output fails with only that as the error, but leaving it out times out every time.

  • Tenbagger Avatar

    I decided to learn Rust's Nom crate. Got a nice solution up and running with Nom, only to experience that Nom is not accepted. Nom has 158+ million downloads, and I will suggest that any rustacean would consider Nom for a task like this.

    Allow Rust Nom crate!

  • Konstantin Modin Avatar

    Nice kata, too easy for 2kyu though

  • lixelv Avatar

    1-st 2 kyu kata in my life! Thanks for this xp, that was awesome. :)

  • Krillan Avatar

    The description contains incomplete information about the task; very important information is missing:

    1. Differences between calling and jumping/how ret works are not clearly described
    2. It is not described that code can move from line to line between functions ( for example, based on Blind4Basics hints https://www.codewars.com/kata/58e61f3d8ff24f774400002c/discuss/python#5c35e71101883f5597eb533d )
  • maartene Avatar

    Loved this Kata! (Swift version) My solution is way over engineered: I ended up creating a full Tokenizer -> Parser -> Interpreter chain. But it was great fun. And something I wanted to explore anyway. Thanks for creating this Kata!

  • yanjinliang Avatar

    This comment has been hidden.

  • kakakiko Avatar

    Could it be updated to a more recent Node version?

    I have finished this on my machine, but I am unable to pass the tests because a bunch of functions and language features are missing.

    Things such as:

    • Named capture groups (/(?<number>\d+)/)
    • String.prototype.at
    • String.prototype.matchAll

    Nevertheless, it was fun to complete!

  • bilel114 Avatar

    Thank you for this kata. Took some time (and a lot of code) but I highly enjoyed comeing up with a solution just how I wanted it.

  • trashy_incel Avatar

    C:

    • the return value in case of error ((char *)-1) is nonsensical, very bad practice and undocumented;
    • memory allocation of the returned pointer is not documented;
    • tests suite crashes when the expected value is (char *)-1 and the actual value is not;
  • dbtx Avatar

    I have just tried a "solution" that merely printed the program to stderr and returned the program:

    #include <stdio.h>
    
    char* assembler_interpreter (const char* program)
    {
        fprintf(stderr, "%s\n", program);
        fflush(0);
        return program;
    }
    

    But, the program_fail sample test always segfaults anyway. I think the problem is that for the "expected" argument to shouldBe(), the test definition casts the value -1 to a (const char *) which IIUC is equal to the maximum value of a size_t. Then shouldBe() compares that to detect whether it is supposed to be anything. OK. But it seems cr_assert_str_eq() then tries to access/dereference it, unconditionally. At least, if I put that -1 in quotes, or return from shouldBe() before that, it prevents the crash. Of course you pass the test and avoid the crash by returning -1 but it seems to be an odd case of the test crashing and not the solution.

  • F1reKnight Avatar

    I did it! Thanks for kata

  • HaoticEvil Avatar

    Very interesting kata. It took some time, but it was a pleasure. Thanks to the author:)

  • Root-Exec Avatar

    Language C:

    Looking for some hints for the actual test cases. I'm able to pass all example cases and one of the random ones. However, I keep getting stuck with a SEGFAULT Invalid Memory Access. Obviously I cannot print out the test case during a SEGFAULT, but I'm trying to think of edge cases where my program could SEFAULT. I can't think of weird inputs that would cause an invalid memory access. Are there any "gotcha's" in the submission cases that I'm missing?

  • Goose532_ Avatar

    Can someone please explain to me why this test case should return -1?

    call  func1
    call  print
    end
    
    func1:
        call  func2
        ret
    
    func2:
        ret
    
    print:
        msg 'This program should return -1'
    
  • AlexOreL Avatar

    Wrote my first 64-bit C++ assembler interpreter on my CS studies in university. Then it was about 1000 lines of code (although there were about a hundred functions instead of 20). Now it is 150 lines in JS. Pretty kata, i like it!

  • ValeryVB Avatar

    I don't understand why it's a 2 kyu kata - it is rather simple. The only tricky things to me was "msg" command. You have to check if comma is a separator or just is in the substring to be printed.

    There is 4 kyu kata that is more difficult to me (find all correct fraction with given denominator). Still "timeout" there. :-(

  • Persa Avatar

    Very nice kata i enjoyed so much but if you wrote in assembly and knew how things work in assembly it is actually too easy to write.

  • jrom99 Avatar

    I think the kata description should've mentioned that labels/coroutines themselves can be "run over" and the program should just ignore them. I've spent a lot of unnecessary time trying to wrap my head around that recursive power function due to this (@Blind4Basics and @AnitaK comments helped a lot, but all necessary information should be available in the kata description or tests).

    Also, even though it's not tested, I think the kata's description should mention that indentation has no particular meaning, since that implies labels/coroutines can be nested.

  • jpssj Avatar

    Hi,

    Some questions :

    • Are the subroutine's definitions always at the end of the program ?
    • Can a subroutine define another subroutine, something like that :
      func1:
        ; some stuff
        func2:
          ; other stuff
          ret
        ret
      
    • Can a subroutine's definition end without a 'ret' ?

    Thanks !

  • Holos Tris Avatar

    I guess program_fibonacci is broken.

    In this segment:

    cmp   c, a
    jle   proc_fib
    ret
    

    Instead of

    jle   proc_fib
    

    Should be

    jl   proc_fib
    
  • zacharybarbanell Avatar

    The sample test cases have "tabs" that are actually several spaces, but the real test cases have tabs that are actually tabs. One of these should be changed so they match.

  • gfreundt Avatar

    I don't usually comment on Katas, but I have to congratulate the author(s) on how much fun and entretaining this one was. Thanks!

  • hrist0stoichev Avatar

    The 2^10 = 1024 test case is wrong (at least for python). The je continue instruction leads to a ret instruction only for the last recursive call. The other calls are then left hanging and the program, therefore, must return -1 because it cannot exit proc_func.

    There are 2 possible solutions:

    1. Add ret at the end of proc_func
    2. Change the recursive call in proc_func to jump proc_func. Then the ret statement will return to the call proc_func statement in the "main" method.

    This is the unmodified test case (without any of the fixes):

    mov   a, 2            ; value1
    mov   b, 10           ; value2
    mov   c, a            ; temp1
    mov   d, b            ; temp2
    call  proc_func
    call  print
    end
    
    proc_func:
        cmp   d, 1
        je    continue
        mul   c, a
        dec   d
        call  proc_func
    
    continue:
        ret
    
    print:
        msg a, '^', b, ' = ', c
        ret
    
  • ElectricZatch Avatar

    Awesome kata!! Thanks! All hail the power of regex too! haha

  • akar-0 Avatar
  • darkmain Avatar

    This comment has been hidden.

  • chippyash Avatar

    I've written one in Go, as the first part allowed for Go. But this second part doesn't . :-( How do we get Go supported?

  • Ihor_Rod Avatar

    Working on Scala When I am sending a code like def interpret(input: String): Option[String] =None or like smth in answer ut's working perfectly well and do compilation, but when I send my code with some realised functions, that works well on my computer - it sends an error message: Test Suite Aborted Exception encountered when invoking run on a nested suite - Unable to load a Suite class that was discovered in the runpath: SampleAssemblerInterpreterSuite

    What is it?

  • WinterShiver Avatar

    This kata may be more interesting if parameter passing is required. 2333

  • WinterShiver Avatar

    The standard of register names is not clarified in detail. In Assembler interpreter (part I), they are described as re alphabetical (letters only). But actually in this kata, to pass the tests, you should allow register names to begin with _/letters and follow by _/letters/numbers, like most common identifiers.

  • WinterShiver Avatar

    Data.HashMap is not supported by the Haskell compiler. Could I use something instead?

  • und3f Avatar

    Overall kata is great but the msg instruction is definately non-assembler and looks like C command.

  • amir650 Avatar

    Great Kata! Thank you.

  • markkraay Avatar

    This comment has been hidden.

  • sovaz1997 Avatar

    The task is fine, but it is very unclear that a function can has "call" instruction without "ret" instruction

  • sj95126 Avatar

    This one's a bit frustrating. I've come up with many ways to write it badly, but can't quite get it done well.

  • eurydice5717 Avatar

    Great kata, full of learnings Tried to follow a CPU/COMPILER/EMULATOR implementation.. and for the first time make use of some C++ features I never used before : . string_view (VERY good for string performance, WARNING should not modify the base string) . variant (IMO very fit for parsing the arguments of any emulator) . 'if init' (GREAT)

  • akar-0 Avatar

    In JS, at first my code passed all tests except the "program_fibonacci" basic test because it did not handle properly the case where the register had the value 0. However I could cheat the tests adding a special returned value for this case. I guess that means there are no other cases where the register can have the value 0. Maybe the tests could be reinforced in that languages by adding some random cases with the same configuration.

  • wang_wbq Avatar
  • xlamsp Avatar

    Very nice kata, thanks!

  • cyqsimon Avatar

    Question should specify the field we are operating in, i.e. 16 or 32 or 64 or 128 bit int, signed or unsigned.

    Also the msg instruction can be worded more clearly. For example,

    Each item in the list of arguments is either a register, or a string literal delimited by '. The list should be concatenated and stored as output.

  • ulfk Avatar

    I'm a bit confused why the syntax changes compared to the first part. Why have you introduced the commas? Also the change of the function's return type causes that all tests from the first part need to be adapted. The resulting message could have been a special 'msg'-register in the returned dictionary.

  • iwtga Avatar

    Finally, Solved it!!!! Took me 6 hours, had my tea and dinner alongside hahah! The return part was confusing also the 'msg' command was a bit tricky. Everything aside, it was a satisfying kata!

  • lemmi Avatar

    Thank you for this great kata. Amazingly, the implementation of the msg-routine took here the most time.

  • john_connor Avatar

    Do you really want the cmp instruction to compare two integer constants in one of its forms? Which of the known assemblers has such a form? It doesn't make sense.

  • iamadamant Avatar

    Where i was wrong?

    Program is: mov a, 11 ; value1 mov b, 3 ; value2 call mod_func msg 'mod(', a, ', ', b, ') = ', d ; output end

    ; Mod function mod_func: mov c, a ; temp1 div c, b mul c, b mov d, a ; temp2 sub d, c ret

    My output is 0, but should be 2. How i know i am right but i have error there

  • SunMaster Avatar

    Btw, a very fun to solve kata

  • SunMaster Avatar

    When doing the c-version there's a large number of warnings. It seems it's connected to the upgrade to clang 8. There's so many it's hard to find my own errors :-)

  • MobulaKuhlii Avatar
  • kopernikus Avatar

    I had to std::cout the tokens while parsing the program, otherwise the server would timeout, that's strange! Any idea why that could happen?

  • ACWUser Avatar

    Loved, loved, loved this kata. Really fun!

  • Olimpo Carpio Avatar

    Debería ser de nivel 1

  • Goose Typed Avatar

    This comment has been hidden.

  • gui3 Avatar

    Wonderful kata ! thanks for the challenge !

  • SubtRose Avatar

    Do i need realize a error handling? Or input will be correctly anyway?

  • DevTony101 Avatar

    Amazing kata! Solving it was equally fun and frustrating. Bravo 👌

  • Kantoelite11 Avatar

    I imagine completing this in C will be a huge task.....

  • Kantoelite11 Avatar

    can we write a different class for parser in c#?i tested it but it looks like u can only write a single class.....

  • qmstuart Avatar

    What would happen if the 'end' command doesn't exist in this example:

    "mov a, 5 inc a call function msg '(5+1)/2 =', a

    function: div a, 2 ret "

    Does execution carry straight through to the function and end when the instruction pointer is beyond the last instruction?

    i.e. will it call function, then set msg then divide a by 2 and then return... return to where? Or does ret only count if its in a function call?

  • Expurple Avatar

    This one is just pure joy. I've spent two days on it. I rarely have courage to finish my solutions where unexpected unclear bugs appear, but this time I even enjoyed the process of setting breakpoints and really reading in. Thank you.

  • Arganancer Avatar

    I really enjoyed working on this! Compared to other difficult Katas, the challenge in this one was making sure the structure of my solution was solid. Great addition to the Simple Interpreter Kata. Highly recommend completing it first as the author said.

  • warismycode Avatar

    This comment has been hidden.

  • jimstr Avatar

    This is a fantastic exercise. Many thanks!

  • dmercertaylor Avatar

    It would be nice if the description clarified the relationship between cmp and subroutines (i.e. should subroutines affect the value of the parent "most recent cmp" or get their own). I don't believe this case is tested either way, though.

  • greenghost Avatar

    Great Kata! :)

  • alexc19 Avatar

    I like this kind of kata, the solution is easy ("just follow the... instructions", no pun intended) and the real challenge lies in writing code that is easy to read and debug (DRY etc.).

    To me the key design choices are as follows:

    • How to parse the source code of the input program. This is not really a choice because regex is the way to go, but if you don't know your regex you can get away with some "manual" splitting, slicing, parsing etc. (ugly!).

    • How to manage the opcode switch in the main loop. You can use switch or if..elif.. statements, or set up a dictionary with opcodes as keys and functions as values (if the language supports first class functions). The latter approach can go all the way down to using the language built-in operator functions. It is elegant but on the downside you end up with a lot of functions.

    • How to manage the program counter (aka instruction pointer). You can defer increments and assignments to the functions that emulate the processor instructions, or increment the program counter at the end of the main loop (unless a jmp instruction was executed).

    • Last but not least, OOP vs functional approach.

      • The OOP approach defines a class that represents the processor: it comes with registers, program counter, stack etc. as data members and some class methods for processor instructions and program execution. Methods can modify data members at any time: this is efficient but can easily turn into debugging hell.
      • The functional approach defines a state data structure that represents a snapshot of the system (registers, program counter, stack etc.). Processor instructions are external, pure functions that take a state as input and return a new state as output. This makes it easier to catch bugs, at the expense of performance, because a new state is created at each execution step.

    P.S. thanks for this kata!

  • olavbs Avatar

    Haskell translation would be really nice!

  • Hana1989 Avatar

    Great kata! :)

  • user7820265 Avatar

    I take a lot of time to finish it,it's too hard for me.I'm in trouble about how to return default -1 and some spetial msg parameters(which contains , nested in '').finally,i complete it,but maybe not very correct about the condition of return -1 without the end command.This is a good kaka of course.

  • jeromemeichelbeck Avatar

    Enjoying this Kata so far (Python right now, JS, maybe php). It will help me making a simple French pseudo code intepreter in JS I've been thinking about lately.

  • AyushBk Avatar

    Recently I've researching alot about Assembly languages when suddenly this challenge appeared. Thoroughly enjoyed this challege..

  • alexgr13 Avatar

    This is a typo in Details. 'to' 2 times.

    jmp lbl - jumps ----> to to <------ the label lbl.

  • olizh Avatar

    I managed to do this with SWIFT and passed the test. But I think there would be a more elegant way to do it in SWIFT, using protocol oriented design. I look forward to seeing and learning from that.

  • kaifeng Avatar

    Thanks for the kata, find some past memory on embedded development ;) Not as hard as other 2kyu katas, just from my angle though.

  • joesamir2010eaf Avatar

    call should never be used as an unconditional jump like the case in the recursive subroutine of the program_power test, because in real assemblers, when CALL is called, it pushes the IP location from where the instruction was called onto the stack, then jumps to the location of the label, and when RET is called the top value of on the stack gets popped back into the IP. In the Test, when CALL is called to jump back to proc_func label, its location gets pushed onto the stack everytime, so that when RET is finally called, to get back to the line after where it was called, it pops back the location of the recursive CALL instead, which cause the program to halt. Please fix it and use JMP instead. Thank you

  • SahandJ Avatar

    I dont get the difference between jmp and call. How are they different?

    jmp lbl: Jumps to the label lbl call lbl: Call to the subroutine identified by lbl

    So for instance jmp func and call func should do the same thing right? If func had a ret, the instruction pointer would return to the jmp or call respectively.

  • HuHguZ Avatar

    This comment has been hidden.

  • nomennescio Avatar

    Please review and approve my C translation

  • Glyxerine Avatar

    This comment has been hidden.

  • AnitaK Avatar

    Is there a difference between the jmp and the call commands?

  • RobertsN Avatar

    Excellent. Rather nasty parsing multiple spaces and the msg format itself.

    Maybe a part III could be done adding, for example:

    • DJNZ
    • Register sizes (say 16 bit) and enable an overflow flag which could add, say JO and JNO
    • Enable relative jumps (not only to labels
    • Add Push and Pop (push with values and/or regs)

    Really enjoyed it

  • dinglemouse Avatar

    Description:

    readability pourposes

    :-)

  • FArekkusu Avatar

    C++ translation. Please, review and approve.

    Note: it includes description update for both Ruby and C++ version, and should be approved last.

  • FArekkusu Avatar

    Ruby translation. Please, review and approve.

  • dpustovarov Avatar

    Why do you not test the case "label and instruction in one line", i.e "repeat: dec b" ?

  • dpustovarov Avatar

    Why do you not test the case "semicolon in string" (JavaScript), i.e "msg 'a = ', a, '; b = ', b" ?

  • KonradLinkowski Avatar

    This comment has been hidden.

  • hobovsky Avatar

    I created C# translation, based on B4B's Java translation. Please verify, and eventually accept.

  • Aelazr Avatar

    Swift version won't pass even when test cases are satisfied because of warnings in the test harness writing to stderr.

    main.swift:20:17: warning: initialization of immutable value 'ans' was never used; consider replacing with assignment to '_' or removing it

    let ans = try assemblerInterpreter(exampleErrorProgram)

    A simple assignment to '_' would suffice for swift 3.

    For swift 4 an additional warning is output to stderr:

    main.swift:197:32: warning: 'characters' is deprecated: Please use String or Substring directly

    let code = rawCode.characters.map { String($0) }

  • Jomopipi Avatar

    in the description for mul x, y you spelled 'with' as 'mith'. this isn't runescape

  • Keozon Avatar

    Good kata, fairly straightforward, though. Only thing that tripped me up was parsing the msg format.

  • metalim Avatar
  • sfoulk Avatar

    Also, not to get too far ahead, which kata is Part 1?

  • sfoulk Avatar

    Hmm. Just found this, and I am an old Assembly programmer! Thank you, but this sure seems like it should be a level 1. Irregardless, I am looking forward to coding it!

  • JohanWiltink Avatar

    What are the possible names of the registers?

  • joh_pot Avatar

    Does a ; comment end when it encounters an opcode, or when a newline is encountered? I.e is this a comment still ; this is a mov a , 5 comment

  • Voile Avatar
  • Pengeszikra Avatar

    Will you be add the javascript to this kata?

  • anter69 Avatar

    Really liked this kata! But the inevitable messing with regex gave me quite a headache...

  • nomennescio Avatar

    Nice kata, but I somewhat dislike the unclean use of spaces and commas to separate fields. With a proper syntax, the solution could have become a lot cleaner.

  • Voile Avatar

    Thanks for reminding me that this kata exists ;-)

    Took half an hour to finish it and approved it.

  • Blind4Basics Avatar

    Java translation, please review and approve.

  • Blind4Basics Avatar

    This one is just EXCELLENT! :)

    Some troubles with the description, as in the part I, but not so much. I'll try to do a java translation and I'll make some modifications to the description at the same time.

    Despite the previous ranking suggestions, I believe this should be ranked 2 kyu because:

    • all interpreters on cw are overranked
    • this one is harder than the boolfuck interpreter (you need to build your own tokenizer)

    btw:

    • the class used to create the random tests is defined 2 times in the test cases
    • is that really useful to do 1024 random tests...? :o
  • e666666 Avatar

    This happen on 9nd test Traceback: in File "/usr/lib/python3.6/random.py", line 274, in shuffle x[i], x[j] = x[j], x[i] KeyError: 0

    And after i put a print on the beginning of my code nothing appear so the test case maybe broke.

  • smile67 Avatar

    Is it allowed to call a function inside a function - would be a little bit more work (good to know before implementing and a point for your description);-)?