Task: Starting a web browser

C: 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "wren.h"



void C_fileAllocate(WrenVM* vm) {
    FILE** pfp = (FILE**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(FILE*));
    const char *filename = wrenGetSlotString(vm, 1);
    const char *mode = wrenGetSlotString(vm, 2);
    *pfp = fopen(filename, mode);
}

void C_write(WrenVM* vm) {
    FILE* fp = *(FILE**)wrenGetSlotForeign(vm, 0);
    const char *s = wrenGetSlotString(vm, 1);
    fputs(s, fp);
}

void C_close(WrenVM* vm) {
    FILE* fp = *(FILE**)wrenGetSlotForeign(vm, 0);
    fclose(fp);
}

void C_remove(WrenVM* vm) {
    const char *filename = wrenGetSlotString(vm, 1);
    remove(filename);
}

void C_flushAll(WrenVM* vm) {
    fflush(NULL);
}

void C_system(WrenVM* vm) {
    const char *s = wrenGetSlotString(vm, 1);
    system(s);
}

void C_sleep(WrenVM* vm) {
    int seconds = (int)wrenGetSlotDouble(vm, 1);
    sleep(seconds);
}

WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
    WrenForeignClassMethods methods;
    methods.allocate = NULL;
    methods.finalize = NULL;
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "File") == 0) {
            methods.allocate = C_fileAllocate;
        }
    }
    return methods;
}

WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature) {
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "File") == 0) {
            if (!isStatic && strcmp(signature, "write(_)") == 0)   return C_write;
            if (!isStatic && strcmp(signature, "close()") == 0)    return C_close;
            if ( isStatic && strcmp(signature, "remove(_)") == 0)  return C_remove;
            if ( isStatic && strcmp(signature, "flushAll()") == 0) return C_flushAll;
        } else if (strcmp(className, "C") == 0) {
            if ( isStatic && strcmp(signature, "system(_)") == 0)  return C_system;
            if ( isStatic && strcmp(signature, "sleep(_)") == 0)   return C_sleep;
        }
    }
    return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
    switch (errorType) {
        case WREN_ERROR_COMPILE:
            printf("[%s line %d] [Error] %s\n", module, line, msg);
            break;
        case WREN_ERROR_STACK_TRACE:
            printf("[%s line %d] in %s\n", module, line, msg);
            break;
        case WREN_ERROR_RUNTIME:
            printf("[Runtime Error] %s\n", msg);
            break;
    }
}

char *readFile(const char *fileName) {
    FILE *f = fopen(fileName, "r");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    rewind(f);
    char *script = malloc(fsize + 1);
    fread(script, 1, fsize, f);
    fclose(f);
    script[fsize] = 0;
    return script;
}

static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
    if( result.source) free((void*)result.source);
}

WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
    WrenLoadModuleResult result = {0};
    if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
        result.onComplete = loadModuleComplete;
        char fullName[strlen(name) + 6];
        strcpy(fullName, name);
        strcat(fullName, ".wren");
        result.source = readFile(fullName);
    }
    return result;
}

int main(int argc, char **argv) {
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.bindForeignClassFn = &bindForeignClass;
    config.bindForeignMethodFn = &bindForeignMethod;
    config.loadModuleFn = &loadModule;
    WrenVM* vm = wrenNewVM(&config);
    const char* module = "main";
    const char* fileName = "starting_web_browser.wren";
    char *script = readFile(fileName);
    WrenInterpretResult result = wrenInterpret(vm, module, script);
    switch (result) {
        case WREN_RESULT_COMPILE_ERROR:
            printf("Compile Error!\n");
            break;
        case WREN_RESULT_RUNTIME_ERROR:
            printf("Runtime Error!\n");
            break;
        case WREN_RESULT_SUCCESS:
            break;
    }
    wrenFreeVM(vm);
    free(script);
    return 0;
}




Go: package main

import (
    "fmt"
    "html/template"
    "log"
    "os"
    "os/exec"
    "strings"
    "time"
)

type row struct {
    Address, Street, House, Color string
}

func isDigit(b byte) bool {
    return '0' <= b && b <= '9'
}

func separateHouseNumber(address string) (street string, house string) {
    length := len(address)
    fields := strings.Fields(address)
    size := len(fields)
    last := fields[size-1]
    penult := fields[size-2]
    if isDigit(last[0]) {
        isdig := isDigit(penult[0])
        if size > 2 && isdig && !strings.HasPrefix(penult, "194") {
            house = fmt.Sprintf("%s %s", penult, last)
        } else {
            house = last
        }
    } else if size > 2 {
        house = fmt.Sprintf("%s %s", penult, last)
    }
    street = strings.TrimRight(address[:length-len(house)], " ")
    return
}

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

var tmpl = `
<head>
  <title>Rosetta Code - Start a Web Browser</title>
  <meta charset="UTF-8">
</head>
<body bgcolor="#d8dcd6">
  <table border="2">
    <p align="center">
      <font face="Arial, sans-serif" size="5">Split the house number from the street name</font>    
      <tr bgcolor="#02ccfe"><th>Address</th><th>Street</th><th>House Number</th></tr>
      {{range $row := .}}
      <tr bgcolor={{$row.Color}}>         
        <td>{{$row.Address}}</td>
        <td>{{$row.Street}}</td>
        <td>{{$row.House}}</td>
      </tr>
      {{end}}
    </p>
  </table>
</body>
`
func main() {
    addresses := []string{
        "Plataanstraat 5",
        "Straat 12",
        "Straat 12 II",
        "Dr. J. Straat   12",
        "Dr. J. Straat 12 a",
        "Dr. J. Straat 12-14",
        "Laan 1940 - 1945 37",
        "Plein 1940 2",
        "1213-laan 11",
        "16 april 1944 Pad 1",
        "1e Kruisweg 36",
        "Laan 1940-'45 66",
        "Laan '40-'45",
        "Langeloërduinen 3 46",
        "Marienwaerdt 2e Dreef 2",
        "Provincialeweg N205 1",
        "Rivium 2e Straat 59.",
        "Nieuwe gracht 20rd",
        "Nieuwe gracht 20rd 2",
        "Nieuwe gracht 20zw /2",
        "Nieuwe gracht 20zw/3",
        "Nieuwe gracht 20 zw/4",
        "Bahnhofstr. 4",
        "Wertstr. 10",
        "Lindenhof 1",
        "Nordesch 20",
        "Weilstr. 6",
        "Harthauer Weg 2",
        "Mainaustr. 49",
        "August-Horch-Str. 3",
        "Marktplatz 31",
        "Schmidener Weg 3",
        "Karl-Weysser-Str. 6",
    }
    browser := "firefox" 
    colors := [2]string{"#d7fffe", "#9dbcd4"}
    fileName := "addresses_table.html"
    ct := template.Must(template.New("").Parse(tmpl))
    file, err := os.Create(fileName)
    check(err)
    rows := make([]row, len(addresses))
    for i, address := range addresses {
        street, house := separateHouseNumber(address)
        if house == "" {
            house = "(none)"
        }
        color := colors[i%2]
        rows[i] = row{address, street, house, color}
    }   
    err = ct.Execute(file, rows)
    check(err)
    cmd := exec.Command(browser, fileName)
    err = cmd.Run()
    check(err)
    file.Close()
    time.Sleep(5 * time.Second) 
    err = os.Remove(fileName)
    check(err)
}