Introduction
About 381 wordsAbout 1 min
2025-10-08
Overview
The theme uses Shiki to implement syntax highlighting in Markdown code blocks.
Important Changes 1.0.0-rc.136
Starting from version 1.0.0-rc.136, the theme has migrated the code highlighting plugin from the internally implemented @vuepress-plume/plugin-shikiji
to @vuepress/plugin-shiki provided by the vuepress ecosystem.
(No need to worry about significant changes - I am also one of the main developers of@vuepress/plugin-shiki
, which implements functionality consistent with the theme's original plugin.)
Some configuration items require adjustments:
- The
languages
configuration has been changed to thelangs
option. You no longer need to manually add the languages you use; the plugin will automatically recognize and load language packages as needed. - The
themes
configuration has been changed to:- When using a single theme configuration, use the
theme
option to configure the code block theme - When using dual theme configuration, use the
themes
option to configure the code block themes.
- When using a single theme configuration, use the
Languages
Shiki supports over 190+ languages. You can view the complete list of supported languages at languages.
You can use the following syntax to enable highlighting for code written in your chosen language:
``` [lang]
<!-- Your code content -->
```
Where [lang]
represents the programming language you are using.
Example:
``` js
const a = 1
console.log(a)
```
const a = 1
console.log(a)
Highlighting Themes
Shiki supports over 40+ highlighting themes.
You can find the complete list of supported themes at Themes and customize the highlighting theme according to your preference.
Theme Plume's default configuration for code block themes:
export default defineUserConfig({
theme: plumeTheme({
codeHighlighter: {
themes: { light: 'vitesse-light', dark: 'vitesse-dark' },
}
})
})
The default configuration supports using the vitesse-light
/vitesse-dark
themes for light/dark modes respectively.
Additional Features
Thanks to the powerful capabilities of Shiki, Theme Plume provides additional feature support for code blocks, enhancing their expressive power.
Additionally, to facilitate better code demonstrations, Theme Plume provides syntax support for embedding CodePen, Js Fiddle, Code Sandbox, and Replit, allowing you to easily embed code demonstrations.
Examples
#include <stdio.h>
#define ARR_LEN 7
void qsort(int v[], int left, int right);
void printArr(int v[], int len);
int main()
{
int i;
int v[ARR_LEN] = { 4, 3, 1, 7, 9, 6, 2 };
printArr(v, ARR_LEN);
qsort(v, 0, ARR_LEN-1);
printArr(v, ARR_LEN);
return 0;
}
void qsort(int v[], int left, int right)
{
int i, last;
void swap(int v[], int i, int j);
if (left >= right)
return;
swap(v, left, (left + right) / 2);
last = left;
for (i = left+1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i);
swap(v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
void swap(int v[], int i, int j)
{
int temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
void printArr(int v[], int len)
{
int i;
for (i = 0; i < len; i++)
printf("%d ", v[i]);
printf("\n");
}
// Working of implicit type-conversion
#include <iostream>
using namespace std;
int main() {
int num_int;
double num_double = 9.99;
// implicit conversion
// assigning a double value to an int variable
num_int = num_double;
cout << "num_int = " << num_int << endl;
cout << "num_double = " << num_double << endl;
return 0;
}
import java.awt.Rectangle;
public class ObjectVarsAsParameters
{ public static void main(String[] args)
{ go();
}
public static void go()
{ Rectangle r1 = new Rectangle(0,0,5,5);
System.out.println("In method go. r1 " + r1 + "\n");
// could have been
//System.out.prinltn("r1" + r1.toString());
r1.setSize(10, 15);
System.out.println("In method go. r1 " + r1 + "\n");
alterPointee(r1);
System.out.println("In method go. r1 " + r1 + "\n");
alterPointer(r1);
System.out.println("In method go. r1 " + r1 + "\n");
}
public static void alterPointee(Rectangle r)
{ System.out.println("In method alterPointee. r " + r + "\n");
r.setSize(20, 30);
System.out.println("In method alterPointee. r " + r + "\n");
}
public static void alterPointer(Rectangle r)
{ System.out.println("In method alterPointer. r " + r + "\n");
r = new Rectangle(5, 10, 30, 35);
System.out.println("In method alterPointer. r " + r + "\n");
}
}
package com.example.kotlin
import java.util.Random as Rand
import android.support.v7.app.AppCompatActivity
import org.amshove.kluent.`should equal` as Type
fun main(@NonNull args: Array<String>) {
println("Hello Kotlin! ${/*test*/}")
val map = mutableMapOf("A" to "B")
thing.apply("random string here \n\t\r")
thing.let { test: -> }
val string = "${getThing()}"
}
val items = listOf("apple", "banana", "kiwifruit")
var x = 9
const val CONSTANT = 99
@get:Rule
val activityRule = ActivityTestRule(SplashActivity::class.java)
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val float = 0.043_331F
val bytes = 0b11010010_01101001_10010100_10010010
if(test == "") {
1 and 2 not 3
} else {
}
fun <T> foo() {
val x = Bar::class
val y = hello?.test
}
suspend fun <T, U> SequenceBuilder<Int>.yieldIfOdd(x: Int) {
if (x % 2 != 0) yield(x)
}
val function = fun(@Inject x: Int, y: Int, lamda: (A, B) -> Unit): Int {
test.test()
return x + y;
}
abstract fun onCreate(savedInstanceState: Bundle?)
fun isOdd(x: Int) = x % 2 != 0
fun isOdd(s: String) = s == "brillig" || s == "slithy" || s == "tove"
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
fun foo(node: Node?): String? {
val parent = node.getParent() ?: return null
}
interface Greetable {
fun greet()
}
open class Greeter: Greetable {
companion object {
private const val GREETING = "Hello, World!"
}
override fun greet() {
println(GREETING)
}
}
expect class Foo(bar: String) {
fun frob()
}
actual class Foo actual constructor(val bar: String) {
actual fun frob() {
println("Frobbing the $bar")
}
}
expect fun formatString(source: String, vararg args: Any): String
expect annotation class Test
actual fun formatString(source: String, vararg args: Any) = String.format(source, args)
actual typealias Test = org.junit.Test
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
@file:JvmName("Foo")
private sealed class InjectedClass<T, U> @Inject constructor(
val test: Int = 50,
var anotherVar: String = "hello world"
) : SomeSuperClass(test, anotherVar) {
init {
//
}
constructor(param1: String, param2: Int): this(param1, param2) {
//
}
companion object {
//
}
}
annotation class Suspendable
val f = @Suspendable { Fiber.sleep(10) }
private data class Foo(
/**
* ```
* ($)
* ```
*/
val variables: Map<String, String>
)
data class Response(@SerializedName("param1") val param1: String,
@SerializedName("param2") val param2: String,
@SerializedName("param3") val param3: String) {
}
object DefaultListener : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { }
override fun mouseEntered(e: MouseEvent) { }
}
class Feature : Node("Title", "Content", "Description") {
}
class Outer {
inner class Inner {}
}
def fib(n): # write Fibonacci series up to n
"""Print a Fibonacci series up to n."""
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
# Now call the function we just defined:
fib(2000)
package main
import (
"fmt"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
class LotteryTicket
NUMERIC_RANGE = 1..25
attr_reader :picks, :purchased
def initialize( *picks )
if picks.length != 3
raise ArgumentError, "three numbers must be picked"
elsif picks.uniq.length != 3
raise ArgumentError, "the three picks must be different numbers"
elsif picks.detect { |p| not NUMERIC_RANGE === p }
raise ArgumentError, "the three picks must be numbers between 1 and 25"
end
@picks = picks
@purchased = Time.now
end
end
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
@interface classname : superclassname {
// instance variables
}
+ classMethod1;
+ (return_type)classMethod2;
+ (return_type)classMethod3:(param1_type)param1_varName;
- (return_type)instanceMethod1With1Parameter:(param1_type)param1_varName;
- (return_type)instanceMethod2With2Parameters:(param1_type)param1_varName
param2_callName:(param2_type)param2_varName;
@end
class Residence {
var rooms: [Room] = []
var numberOfRooms: Int {
return rooms.count
}
subscript(i: Int) -> Room {
get {
return rooms[i]
}
set {
rooms[i] = newValue
}
}
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
var address: Address?
}
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*/
protected function schedule(Schedule $schedule): void
{
// $schedule->command('inspire')->hourly();
}
/**
* Register the commands for the application.
*/
protected function commands(): void
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
// Unlike C/C++, there's no restriction on the order of function definitions
fn main() {
// We can use this function here, and define it somewhere later
fizzbuzz_to(100);
}
// Function that returns a boolean value
fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
// Corner case, early return
if rhs == 0 {
return false;
}
// This is an expression, the `return` keyword is not necessary here
lhs % rhs == 0
}
// Functions that "don't" return a value, actually return the unit type `()`
fn fizzbuzz(n: u32) -> () {
if is_divisible_by(n, 15) {
println!("fizzbuzz");
} else if is_divisible_by(n, 3) {
println!("fizz");
} else if is_divisible_by(n, 5) {
println!("buzz");
} else {
println!("{}", n);
}
}
// When a function returns `()`, the return type can be omitted from the
// signature
fn fizzbuzz_to(n: u32) {
for n in 1..=n {
fizzbuzz(n);
}
}
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL
DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks2022 SET RECOVERY BULK_LOGGED;
GO
SELECT * INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2022 SET RECOVERY FULL;
GO
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<book id="bk103">
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-11-17</publish_date>
<description>After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.</description>
</book>
<book id="bk104">
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-03-10</publish_date>
<description>In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.</description>
</book>
<book id="bk105">
<author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-09-10</publish_date>
<description>The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.</description>
</book>
<book id="bk106">
<author>Randall, Cynthia</author>
<title>Lover Birds</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-09-02</publish_date>
<description>When Carla meets Paul at an ornithology
conference, tempers fly as feathers get ruffled.</description>
</book>
<book id="bk107">
<author>Thurman, Paula</author>
<title>Splish Splash</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-11-02</publish_date>
<description>A deep sea diver finds true love twenty
thousand leagues beneath the sea.</description>
</book>
<book id="bk108">
<author>Knorr, Stefan</author>
<title>Creepy Crawlies</title>
<genre>Horror</genre>
<price>4.95</price>
<publish_date>2000-12-06</publish_date>
<description>An anthology of horror stories about roaches,
centipedes, scorpions and other insects.</description>
</book>
<book id="bk109">
<author>Kress, Peter</author>
<title>Paradox Lost</title>
<genre>Science Fiction</genre>
<price>6.95</price>
<publish_date>2000-11-02</publish_date>
<description>After an inadvertant trip through a Heisenberg
Uncertainty Device, James Salway discovers the problems
of being quantum.</description>
</book>
<book id="bk110">
<author>O'Brien, Tim</author>
<title>Microsoft .NET: The Programming Bible</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-09</publish_date>
<description>Microsoft's .NET initiative is explored in
detail in this deep programmer's reference.</description>
</book>
<book id="bk111">
<author>O'Brien, Tim</author>
<title>MSXML3: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-01</publish_date>
<description>The Microsoft MSXML3 parser is covered in
detail, with attention to XML DOM interfaces, XSLT processing,
SAX and more.</description>
</book>
<book id="bk112">
<author>Galos, Mike</author>
<title>Visual Studio 7: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>49.95</price>
<publish_date>2001-04-16</publish_date>
<description>Microsoft Visual Studio 7 is explored in depth,
looking at how Visual Basic, Visual C++, C#, and ASP+ are
integrated into a comprehensive development
environment.</description>
</book>
</catalog>
const std = @import("std");
const parseInt = std.fmt.parseInt;
test "parse integers" {
const input = "123 67 89,99";
const ally = std.testing.allocator;
var list = std.ArrayList(u32).init(ally);
// Ensure the list is freed at scope exit.
// Try commenting out this line!
defer list.deinit();
var it = std.mem.tokenize(u8, input, " ,");
while (it.next()) |num| {
const n = try parseInt(u32, num, 10);
try list.append(n);
}
const expected = [_]u32{ 123, 67, 89, 99 };
for (expected, list.items) |exp, actual| {
try std.testing.expectEqual(exp, actual);
}
}
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>MDN Web Docs Example: Toggling full-screen mode</title>
<link rel="stylesheet" href="styles.css">
<style class="editable">
video::backdrop {
background-color: #448;
}
</style>
<!-- import the webpage's javascript file -->
<script src="script.js" defer></script>
</head>
<body>
<section class="preview">
<video controls
src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"
poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217"
width="620">
Sorry, your browser doesn't support embedded videos. Time to upgrade!
</video>
</section>
<textarea class="playable playable-css" style="height: 100px;">
video::backdrop {
background-color: #448;
}
</textarea>
<textarea class="playable playable-html" style="height: 200px;">
<video controls
src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"
poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217"
width="620">
Sorry, your browser doesn't support embedded videos. Time to upgrade!
</video>
</textarea>
<div class="playable-buttons">
<input id="reset" type="button" value="Reset" />
</div>
</body>
<script src="playable.js"></script>
</body>
</html>
doctype html
html(lang="en")
head
title= pageTitle
script(type='text/javascript').
if (foo) bar(1 + 5);
body
h1 Pug - node template engine
#container.col
if youAreUsingPug
p You are amazing
else
p Get on it!
p.
Pug is a terse and simple templating language with a
strong focus on performance and powerful features.
// Basic authentication
GET http://example.com
Authorization: Basic username password
###
// Digest authentication
GET http://example.com
Authorization: Digest username password
// The request body is provided in place
POST https://example.com:8080/api/html/post HTTP/1.1
Content-Type: application/json
Cookie: key=first-value
{ "key" : "value", "list": [1, 2, 3] }
html {
margin: 0;
background: black;
height: 100%;
}
body {
margin: 0;
width: 100%;
height: inherit;
}
/* the three main rows going down the page */
body > div {
height: 25%;
}
.thumb {
float: left;
width: 25%;
height: 100%;
object-fit: cover;
}
.main {
display: none;
}
.blowup {
display: block;
position: absolute;
object-fit: contain;
object-position: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2000;
}
.darken {
opacity: 0.4;
}
.button {
&-ok {
background-image: url("ok.png");
}
&-cancel {
background-image: url("cancel.png");
}
&-custom {
background-image: url("custom.png");
}
}
.link {
& + & {
color: red;
}
& & {
color: green;
}
&& {
color: blue;
}
&, &ish {
color: cyan;
}
}
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
vendor(prop, args)
-webkit-{prop} args
-moz-{prop} args
{prop} args
border-radius()
vendor('border-radius', arguments)
box-shadow()
vendor('box-shadow', arguments)
button
border-radius 1px 2px / 3px 4px
border-radius() {
-webkit-border-radius: arguments;
-moz-border-radius: arguments;
border-radius: arguments;
}
body a {
font: 12px/1.4 "Lucida Grande", Arial, sans-serif;
background: black;
color: #ccc;
}
form input {
padding: 5px;
border: 1px solid;
border-radius: 5px;
}
function resolveAfter2Seconds(x) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(x)
}, 2000)
})
}
// async function expression assigned to a variable
const add = async function (x) {
const a = await resolveAfter2Seconds(20)
const b = await resolveAfter2Seconds(30)
return x + a + b
}
add(10).then((v) => {
console.log(v) // prints 60 after 4 seconds.
});
// async function expression used as an IIFE
(async function (x) {
const p1 = resolveAfter2Seconds(20)
const p2 = resolveAfter2Seconds(30)
return x + (await p1) + (await p2)
})(10).then((v) => {
console.log(v) // prints 60 after 2 seconds.
})
function Item({ name, isPacked }) {
if (isPacked)
return null
return <li className="item">{name}</li>
}
export default function PackingList() {
return (
<section>
<h1>Sally Ride's Packing List</h1>
<ul>
<Item
isPacked={true}
name="Space suit"
/>
<Item
isPacked={true}
name="Helmet with a golden leaf"
/>
<Item
isPacked={false}
name="Photo of Tam"
/>
</ul>
</section>
)
}
enum LogLevel {
ERROR,
WARN,
INFO,
DEBUG,
}
/**
* This is equivalent to:
* type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
*/
type LogLevelStrings = keyof typeof LogLevel
function printImportant(key: LogLevelStrings, message: string) {
const num = LogLevel[key]
if (num <= LogLevel.WARN) {
console.log('Log level key is:', key)
console.log('Log level value is:', num)
console.log('Log level message is:', message)
}
}
printImportant('ERROR', 'This is a message')
// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
return (
<ul>
{posts.map(post => (
<li>{post.title}</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts
}
}
}
export default Blog
---
// Your component script here!
import Banner from '../components/Banner.astro';
import ReactPokemonComponent from '../components/ReactPokemonComponent.jsx';
const myFavoritePokemon = [/* ... */];
const { title } = Astro.props;
---
<!-- HTML comments supported! -->
{/* JS comment syntax is also valid! */}
<Banner />
<h1>Hello, world!</h1>
<!-- Use props and other variables from the component script: -->
<p>{title}</p>
<!-- Include other UI framework components with a `client:` directive to hydrate: -->
<ReactPokemonComponent client:visible />
<!-- Mix HTML with JavaScript expressions, similar to JSX: -->
<ul>
{myFavoritePokemon.map((data) => <li>{data.name}</li>)}
</ul>
<!-- Use a template directive to build class names from multiple strings or even objects! -->
<p class:list={["add", "dynamic", {classNames: true}]} />
<script setup>
import { ref } from 'vue'
const message = ref('Hello World!')
function reverseMessage() {
// Access/mutate the value of a ref via
// its .value property.
message.value = message.value.split('').reverse().join('')
}
function notify() {
alert('navigation was prevented.')
}
</script>
<template>
<h1>{{ message }}</h1>
<button @click="reverseMessage">
Reverse Message
</button>
<button @click="message += '!'">
Append "!"
</button>
<a href="https://vuejs.org" @click.prevent="notify">
A link with e.preventDefault()
</a>
</template>
<style>
button, a {
display: block;
margin-bottom: 1em;
}
</style>
<script>
let files;
$: if (files) {
// Note that `files` is of type `FileList`, not an Array:
// https://developer.mozilla.org/en-US/docs/Web/API/FileList
console.log(files);
for (const file of files) {
console.log(`${file.name}: ${file.size} bytes`);
}
}
</script>
<label for="avatar">Upload a picture:</label>
<input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
<label for="many">Upload multiple files of any type:</label>
<input bind:files id="many" multiple type="file" />
{#if files}
<h2>Selected files:</h2>
{#each Array.from(files) as file}
<p>{file.name} ({file.size} bytes)</p>
{/each}
{/if}
(module
;; add the $even_check function to the top of the module
(func $even_check (param $n i32) (result i32)
local.get $n
i32.const 2
i32.rem_u ;; if you take the remainder of a division by 2
i32.const 0 ;; even numbers will have a remainder 0
i32.eq ;; $n % 2 == 0
)
;; add the $eq_2 function after $even_check
(func $eq_2 (param $n i32) (result i32)
local.get $n
i32.const 2
i32.eq ;; returns 1 if $n == 2
)
;; add $multiple_check after $eq_2
(func $multiple_check (param $n i32) (param $m i32) (result i32)
local.get $n
local.get $m
i32.rem_u ;; get the remainder of $n / $m
i32.const 0 ;; I want to know if the remainder is 0
i32.eq ;; that will tell us if $n is a multiple of $m
)
;; add the is_prime exported function after $multiple_check
(func (export "is_prime") (param $n i32) (result i32)
(local $i i32)
(if (i32.eq (local.get $n) (i32.const 1)) ;; 1 is not prime
(then
i32.const 0
return
))
(if (call $eq_2 (local.get $n)) ;; check to see if $n is 2
(then
i32.const 1 ;; 2 is prime
return
)
)
(block $not_prime
(call $even_check (local.get $n))
br_if $not_prime ;; even numbers are not prime (except 2)
(local.set $i (i32.const 1))
(loop $prime_test_loop
(local.tee $i (i32.add (local.get $i) (i32.const 2) ) ) ;; $i += 2
local.get $n ;; stack = [$n, $i]
i32.ge_u ;; $i >= $n
if ;; if $i >= $n, $n is prime
i32.const 1
return
end
(call $multiple_check (local.get $n) (local.get $i))
br_if $not_prime ;; if $n is a multiple of $i this is not prime
br $prime_test_loop ;; branch back to top of loop
) ;; end of $prime_test_loop loop
) ;; end of $not_prime block
i32.const 0 ;; return false
)
) ;; end of module