diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b0d87a79e5da3885c61d060c2a615cf3092ee22e
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,18 @@
+platform:
+- x86
+- x64
+version: 1.0.{build}
+os: Visual Studio 2015
+build_script:
+- '@echo off'
+- setlocal
+- ps: >-
+    If ($env:Platform -Match "x86") {
+      $env:VCVARS_PLATFORM="x86"
+    } Else {
+      $env:VCVARS_PLATFORM="amd64"
+    }
+- call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM%
+- call tools\windows\build.bat
+- call tools\windows\build_examples.bat
+- exit /b 0
diff --git a/tools/windows/README.md b/tools/windows/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3b28eea4af4d8c436d747e3117e947c38411453c
--- /dev/null
+++ b/tools/windows/README.md
@@ -0,0 +1 @@
+Support tools for the Windows (win32/win64) port.
\ No newline at end of file
diff --git a/tools/windows/build.bat b/tools/windows/build.bat
new file mode 100644
index 0000000000000000000000000000000000000000..20f878acab296420cb8b29fa36df74aad26eeb44
--- /dev/null
+++ b/tools/windows/build.bat
@@ -0,0 +1,47 @@
+@echo off
+setlocal
+
+REM This script must be run after vcvarsall.bat has been run,
+REM so that cl.exe is in your path.
+where cl.exe || goto vsmissing_err
+
+REM HEREPATH is <drive_letter>:<script_directory>
+set HEREPATH=%~d0%~p0
+
+REM Set up SRC, BUILD and CLFLAGS
+call %HEREPATH%\env.bat
+call %HEREPATH%\clvars.bat
+
+echo SRC=%SRC%, BUILD=%BUILD%
+echo Building with flags: %CLFLAGS%
+
+pushd %SRC%
+mkdir %BUILD%\obj
+del /Q %BUILD%\obj\
+
+cl.exe -nologo -FC -EHsc -Z7 -Oi -GR- -Gm- %CLFLAGS% -c ^
+       @%HEREPATH%\hammer_lib_src_list ^
+       -Fo%BUILD%\obj\
+if %errorlevel% neq 0 goto err
+
+lib.exe %BUILD%\obj\*.obj -OUT:%BUILD%\hammer.lib
+echo STATIC_LIBRARY %BUILD%\hammer.lib
+if %errorlevel% neq 0 goto err
+popd
+
+REM TODO(uucidl): how to build and run the tests? They are written with glib.h
+REM which might be a challenge on windows. On the other hand the API of glib.h
+REM does not seem too hard to reimplement.
+
+echo SUCCESS: Successfully built
+endlocal
+exit /b 0
+
+:vsmissing_err
+echo ERROR: CL.EXE missing. Have you run vcvarsall.bat?
+exit /b 1
+
+:err
+endlocal
+echo ERROR: Failed to build
+exit /b %errorlevel%
diff --git a/tools/windows/build_examples.bat b/tools/windows/build_examples.bat
new file mode 100644
index 0000000000000000000000000000000000000000..3bbcccb06b8aa92cf54c0fe18547e06b2e461115
--- /dev/null
+++ b/tools/windows/build_examples.bat
@@ -0,0 +1,56 @@
+@echo off
+setlocal
+
+REM This script must be run after vcvarsall.bat has been run,
+REM so that cl.exe is in your path.
+where cl.exe || goto vsmissing_err
+
+REM HEREPATH is <drive_letter>:<script_directory>
+set HEREPATH=%~d0%~p0
+
+REM Set up SRC, BUILD and CLFLAGS
+call %HEREPATH%\env.bat
+call %HEREPATH%\clvars.bat
+
+REM type conversion of a return value
+set CLFLAGS=%CLFLAGS% -wd4242
+
+echo SRC=%SRC%, BUILD=%BUILD%
+echo CLFLAGS=%CLFLAGS%
+
+set HAMMERLIB=%BUILD%\hammer.lib
+
+REM Now let's build some example programs
+
+cl.exe -nologo %CLFLAGS% examples\base64.c %HAMMERLIB% -Fo%BUILD%\ -Fe%BUILD%\
+if %errorlevel% neq 0 goto err
+echo PROGRAM build\base64.exe
+cl.exe -nologo %CLFLAGS% examples\base64_sem1.c %HAMMERLIB%  -Fo%BUILD%\ -Fe%BUILD%\
+if %errorlevel% neq 0 goto err
+echo PROGRAM build\base64_sem1.exe
+cl.exe -nologo %CLFLAGS% examples\base64_sem2.c %HAMMERLIB%  -Fo%BUILD%\ -Fe%BUILD%\
+if %errorlevel% neq 0 goto err
+echo PROGRAM build\base64_sem2.exe
+
+REM FIXME(windows) TODO(uucidl): dns.c only works on posix
+REM cl.exe -nologo %CLFLAGS% examples\dns.c %HAMMERLIB% -Fo%BUILD%\ -Fe%BUILD%\
+REM if %errorlevel% neq 0 goto err
+REM echo PROGRAM build\dns.exe
+
+REM FIXME(windows) TODO(uucidl): grammar.c needs to be fixed
+cl.exe -nologo %CLFLAGS% examples\ties.c examples\grammar.c %HAMMERLIB% -Fo%BUILD%\ -Fe%BUILD%\
+if %errorlevel% neq 0 goto err
+echo PROGRAM build\ties.exe
+
+echo SUCCESS: Successfully built
+endlocal
+exit /b 0
+
+:vsmissing_err
+echo ERROR: CL.EXE missing. Have you run vcvarsall.bat?
+exit /b 1
+
+:err
+echo ERROR: Failed to build
+endlocal
+exit /b %errorlevel%
diff --git a/tools/windows/clvars.bat b/tools/windows/clvars.bat
new file mode 100644
index 0000000000000000000000000000000000000000..c08ed173dd8cc683993017b907406fe50822896d
--- /dev/null
+++ b/tools/windows/clvars.bat
@@ -0,0 +1,37 @@
+REM Don't call me directly
+REM Exports CLFLAGS
+
+REM Start with the most strict warning level
+set WARNINGS=-W4 -Wall -WX
+
+REM We disable implicit casting warnings (c4244), as they occur too often here.
+REM Its gcc/clang counterpart is Wconversion which does not seem to
+REM be enabled by default.
+REM See: [[https://gcc.gnu.org/wiki/NewWconversion#Frequently_Asked_Questions]]
+set WARNINGS=%WARNINGS% -wd4244
+
+REM c4100 (unreferenced formal parameter) is equivalent to -Wno-unused-parameter
+set WARNINGS=%WARNINGS% -wd4100
+
+REM c4200 (zero-sized array) is a C idiom supported by C99
+set WARNINGS=%WARNINGS% -wd4200
+
+REM c4204 (non-constant aggregate initializers) ressembles C99 support
+set WARNINGS=%WARNINGS% -wd4204
+
+REM c4820 (warnings about padding) is not useful
+set WARNINGS=%WARNINGS% -wd4820
+
+REM c4710 (inlining could not be performed) is not useful
+set WARNINGS=%WARNINGS% -wd4710
+
+REM c4255 ( () vs (void) ambiguity) is not useful
+set WARNINGS=%WARNINGS% -wd4255
+
+REM c4996 (deprecated functions)
+set WARNINGS=%WARNINGS% -wd4996
+
+REM we use sprintf
+set DEFINES=-D_CRT_SECURE_NO_WARNINGS
+
+set CLFLAGS=%DEFINES% %WARNINGS%
diff --git a/tools/windows/env.bat b/tools/windows/env.bat
new file mode 100644
index 0000000000000000000000000000000000000000..4037578cccb96202cdd20541cb84932e22a663ab
--- /dev/null
+++ b/tools/windows/env.bat
@@ -0,0 +1,16 @@
+REM Don't call me directly.
+REM
+REM Expects HEREPATH (this directory)
+REM Exports SRC (hammer's src directory)
+REM Exports BUILD (hammer's build directory)
+
+set TOP=%HEREPATH%..\..
+
+REM Get canonical path for TOP
+pushd .
+cd %TOP%
+set TOP=%CD%
+popd
+
+set SRC=%TOP%\src
+set BUILD=%TOP%\build
diff --git a/tools/windows/hammer_lib_src_list b/tools/windows/hammer_lib_src_list
new file mode 100644
index 0000000000000000000000000000000000000000..342b63457fc013222276c6025199779a5acd93d8
--- /dev/null
+++ b/tools/windows/hammer_lib_src_list
@@ -0,0 +1,48 @@
+asprintf.c 
+platform_win32.c 
+allocator.c 
+benchmark.c 
+bitreader.c 
+bitwriter.c 
+cfgrammar.c 
+datastructures.c 
+desugar.c 
+glue.c 
+hammer.c 
+pprint.c 
+registry.c
+system_allocator.c 
+parsers/action.c 
+parsers/and.c 
+parsers/attr_bool.c 
+parsers/bind.c 
+parsers/bits.c 
+parsers/butnot.c 
+parsers/ch.c 
+parsers/charset.c 
+parsers/difference.c 
+parsers/end.c 
+parsers/endianness.c 
+parsers/epsilon.c 
+parsers/ignore.c 
+parsers/ignoreseq.c 
+parsers/indirect.c 
+parsers/int_range.c 
+parsers/many.c 
+parsers/not.c 
+parsers/nothing.c 
+parsers/optional.c 
+parsers/permutation.c 	
+parsers/sequence.c 
+parsers/token.c 
+parsers/unimplemented.c 
+parsers/whitespace.c 
+parsers/xor.c 
+parsers/value.c 
+backends/packrat.c
+backends/llk.c
+backends/regex.c
+backends/glr.c
+backends/lalr.c
+backends/lr.c
+backends/lr0.c
diff --git a/tools/windows/status.bat b/tools/windows/status.bat
new file mode 100644
index 0000000000000000000000000000000000000000..4f8bd11f9f7567f32cd17f843d2918ac6fd1e14d
--- /dev/null
+++ b/tools/windows/status.bat
@@ -0,0 +1 @@
+git grep "FIXME(windows)"