Literate Teaching Example

Hans-Georg Eßer

FAU Erlangen-Nürnberg

Chunk: ⟨the program⟩ (1)

  • First of all, the main program file
    • It includes some headers...
    • ... and also the implementation of testdiv3().
  • Yes, we can have several levels of indentation...
  • ... and there's some syntax highlighting and line wrapping.
the program⟩≡
  /* Test program, (c) 2013 The Author */
  
header file inclusion
  
test function

  #define THIS_IS_AN_ENORMOUSLY_LONG_SYMBOLIC_CONS
TANT_NAME 42

  main () {
    int x;
    printf ("Enter number");     // show message
    input (x);                   // read number
    if (testdiv3(x)) {
      printf ("%d is divisible by 3.\n", x);
    } else {
      printf ("%d is not divisible by 3.\n", x);
    }
    return;
  }
                                                    

Chunk: ⟨header file inclusion⟩ (1)

  • We do need some headers.
  • But how many?
  • Watch the multiple line breaks!
header file inclusion⟩≡
  #include <stdio.h>        // for printf()
  #include "../myread.h"    // for input()

  // This has nothing to do with headers, but
  // this way you can see a really long line
  #define YET_ANOTHER_SYMBOLIC_CONSTANT_WHICH_HAS_
A_LONG_NAME_ONLY_THIS_TIME_IT_IS_SO_LONG_THAT_IT
_WILL_SPAN_SEVERAL_LINES_IN_THE_OUTPUT ((42+42)/
42 + 40)   // weird

  typedef struct {  /* this is also
                       something that 
*/

    int i;  // int
    int j;  // more int
  } /* does not belong here! */ useless_t;
                                                    

Chunk: ⟨test function, bad one⟩ (1)

  • It's true: 3 | x if x is in { 3, 6, 9, 12, ... }
  • But is that a good way?
  • We have scrolling code. (Use mouse or cursor up/down.)
test function, bad one⟩≡
  int testdiv3(int x) {
    return (
      (x ==  3) ||
      (x ==  6) ||
      (x ==  9) ||
      (x == 12) ||
      (x == 15) ||
      (x == 18) ||
      (x == 21) ||
      (x == 24) ||
      (x == 27) ||
      (x == 30) ||
      (x == 33) ||
      (x == 36) ||
      (x == 39) ||
      (x == 42) ||
      (x == 45) ||
      (x == 48) ||
      (x == 51) ||
      (x == 54) ||
      (x == 57) ||
      (x == 60) ||
      (x == 63) ||
      (x == 66) ||
      (x == 69) ||    
      (x == 72) ||
      (x == 75) ||
      (x == 78) ||
      (x == 81) ||
      (x == 84) ||
      (x == 87) );
  }
                                                    

Chunk: ⟨directory with comments⟩ (1)

  • Ok. So, this is what it looks like with only half the screen available. This is certainly not the best way of showing this.
  • Once more: this is what it looks like with only half the screen available. This is certainly not the best way of showing this.
directory with comments⟩≡
  [esser@macbookpro:literate-teaching]$ LANG=C ls 
-li
  total 288
  15653128 drwxr-xr-x  5 esser  staff    170 Apr  
1 06:48 Literatur
  15656814 drwxr-xr-x  4 esser  staff    136 Apr  
1 18:27 Software
  15662900 -rwxr-xr-x  1 esser  staff   7698 Apr  
2 02:13 combine.py
  15668192 -rwxr-xr-x  1 esser  staff   4926 Apr  
2 02:18 example.nw
  15643259 -rwxr-xr-x  1 esser  staff   6522 Apr  
2 01:22 export.py
  15658881 drwxr-xr-x  4 esser  staff    136 Apr  
1 17:44 fonts
  15641951 -rw-r--r--  1 esser  staff    395 Mar 3
0 20:45 index.html
  15661490 drwxr-xr-x  6 esser  staff    204 Apr  
1 19:40 logos
  15667494 -rwxr-xr-x  1 esser  staff    683 Apr  
2 01:40 make.sh
  15651837 -rw-r--r--  1 esser  staff  32418 Mar 3
1 22:35 nicEdit.js
  15649904 -rw-r--r--  1 esser  staff   3351 Jun  
7  2012 nicEditorIcons.gif
  15643349 -rw-r--r--  1 esser  staff  12427 Apr  
2 02:21 out.html
  15660031 -rw-r--r--  1 esser  staff  17606 Apr  
2 02:21 out2.html
  15667034 -rw-r--r--  1 esser  staff   1141 Apr  
2 02:21 result.txt
  15658182 drwxr-xr-x  5 esser  staff    170 Apr  
1 17:21 s5-css
  15662226 -rwxr-xr-x  1 esser  staff  34312 Apr  
2 00:24 sched-rr10.nw
                                                    

Chunk: ⟨directory without comments⟩ (1)

directory without comments⟩≡
  [esser@macbookpro:literate-teaching]$ LANG=C ls -li
  total 288
  15653128 drwxr-xr-x  5 esser  staff    170 Apr  1 06:48 Literatur
  15656814 drwxr-xr-x  4 esser  staff    136 Apr  1 18:27 Software
  15662900 -rwxr-xr-x  1 esser  staff   7698 Apr  2 02:13 combine.py
  15668192 -rwxr-xr-x  1 esser  staff   4926 Apr  2 02:18 example.nw
  15643259 -rwxr-xr-x  1 esser  staff   6522 Apr  2 01:22 export.py
  15658881 drwxr-xr-x  4 esser  staff    136 Apr  1 17:44 fonts
  15641951 -rw-r--r--  1 esser  staff    395 Mar 30 20:45 index.html
  15661490 drwxr-xr-x  6 esser  staff    204 Apr  1 19:40 logos
  15667494 -rwxr-xr-x  1 esser  staff    683 Apr  2 01:40 make.sh
  15651837 -rw-r--r--  1 esser  staff  32418 Mar 31 22:35 nicEdit.js
  15649904 -rw-r--r--  1 esser  staff   3351 Jun  7  2012 nicEditorIcons.gif
  15643349 -rw-r--r--  1 esser  staff  12427 Apr  2 02:21 out.html
  15660031 -rw-r--r--  1 esser  staff  17606 Apr  2 02:21 out2.html
  15667034 -rw-r--r--  1 esser  staff   1141 Apr  2 02:21 result.txt
  15658182 drwxr-xr-x  5 esser  staff    170 Apr  1 17:21 s5-css
  15662226 -rwxr-xr-x  1 esser  staff  34312 Apr  2 00:24 sched-rr10.nw
                                                                                            

Chunk: ⟨header file inclusion⟩ (2)

  • Works nicely:
  • When we have an older slide for the same chunk, this one remembers -- and it counts up
  • (see number in brackets)
  • (and see " =" vs. "=")
header file inclusion⟩+≡
    // watch above: this should be +=, not just =
    #include "../somethingelse.h"
                                                    

Chunk: ⟨long code block⟩ (1)

long code block⟩≡
  void syscall_waitpid (struct regs_syscall *r) {
    // ebx: pid of child to wait for
    // ecx: pointer to status
    // edx: options (ignored)
    int chpid = r->ebx;
    int *status = (int*)r->ecx;
    printf ("[%d] in syscall_waitpid, status (1) = 0x%x\n", current_task, status);
    
imagine an even longer code block
    
imagine a code block which is yet longer  
    
    printf ("[%d] waitpid: waiting for pid %d\n", current_task, chpid);
    thread_table[current_task].state = TSTATE_WAITFOR;  thread_table[current_task].waitfor
 = chpid;
    remove_from_ready_queue (current_task);
    add_to_blocked_queue (current_task, &waitpid_queue);

    printf ("[%d] waitpid: calling yield\n", current_task);
    // syscall_yield (r);   // here we yield
    inside_yield = true;
    scheduler (r, SCHED_SRC_WAITFOR);
    
    /*
    if (thread_table[current_task].state != TSTATE_WAITFOR) {
      printf ("[%d] in syscall_waitpid: wrong return!\n", current_task);
      return;
    };
    
*/

      
    // asm ("int $0x81");  // call scheduler
    
    // PROBLEM
    // We come back here after scheduler(), but with the memory and
    // stack of a different thread. This is bad...
    
    inside_yield = false;

    printf ("waitpid: returned from yield (pid=%d)\n", current_task);

    // now we've returned from syscall_yield, the child must have
    // finished
    
    // unblocking this process happens in syscall_exit() !
    // remove_from_blocked_queue (current_task, &waitpid_queue);
    // add_to_ready_queue (current_task);
    
    // return value of waitpid is the process id of the terminated
    // child. We expect that syscall_exit() has updated the waitfor
    // field of the parent's TCB:
    chpid = thread_table[current_task].waitfor;
    if (chpid>0 && chpid[chpid].used) {
      printf ("current_task = %d\n", current_task);
      printf ("chpid = %d\n", chpid);
      r->eax = chpid;
    
      // the exitcode is in the child's exitcode field:
      printf ("in syscall_waitpid, status (2) = 0x%x\n", status);

      printf ("A...\n");
      printf ("in syscall_waitpid. exitcode = %d\n", thread_table[chpid].exitcode);
      printf ("B...\n");
      *status = thread_table[chpid].exitcode;
      printf ("in syscall_waitpid. *status = %d\n", *status);
    
      // now remove child process
    } else {
      // *status = -1;
    }  
    printf ("going to return from syscall_waitpid\n");
    return;
  }
                                                                                            

Chunk: ⟨credits⟩ (1)

credits⟩≡
  // credits:
  // - S5, http://meyerweb.com/eric/tools/s5/
  // - nicEdit, http://nicedit.com/