介绍
635字约2分钟
2024-04-04
概述
主题 使用 Shiki 在 Markdown 代码块实现语法高亮。
相关信息
主题默认 加载了 Shiki 支持的超过 190+ 的 语言,这可能导致 在启用 vuepress 服务时, 需要多等待 300ms ~ 600ms 左右的时间来加载所有的 语言。
因此,如果比较在意 vuepress 启动时间,建议修改配置为仅加载 您所需要的 语言。
示例:
export default defineUserConfig({
theme: plumeTheme({
plugins: {
shiki: {
languages: ['javascript', 'typescript', 'vue', 'bash', 'sh'],
}
}
})
})
v1.0.0-rc.105 更新
随着 shiki
支持的语言越来越丰富,默认加载全部的语言所花费的时间越来越多了, 因此 强烈建议您 手动配置 languages
,仅加载 您需要的 语言。
同时,在您未配置 languages
时,主题会在启动时尝试分析 markdown
文件中的代码块所使用的语言, 并将它们作为 languages
传入给 shiki,这也极大的减少了加载时间。然而随着 项目 markdown
文件数量和内容的增长, 这种方式带来额外的 i/o 开销和解析开销也会越来越长,因此 强烈建议您手动配置 languages
。 :::
语言
Shiki 支持 超过 190+ 种语言, 你可以在 languages 查看所有支持的语言列表。
你可以通过以下语法为你使用的 语言所编写的代码 实现高亮效果:
```[lang]
```
其中,[lang]
为你使用的语言。
示例:
```js
const a = 1
console.log(a)
```
const a = 1
console.log(a)
高亮主题
Shiki 支持 超过 40+ 种高亮主题。
你可以在 Themes 找到所有支持的主题列表,根据个人的喜欢自定义 高亮主题。
Theme Plume 默认为 代码块使用的主题配置:
export default defineUserConfig({
theme: plumeTheme({
plugins: {
shiki: {
theme: { light: 'vitesse-light', dark: 'vitesse-dark' },
}
}
})
})
默认配置支持在 亮色/暗色 模式分别使用 vitesse-light
/vitesse-dark
主题。
更多支持
得益于 Shiki 的强大能力,Theme Plume 还为 代码块 提供了 更多的 特性支持,它们让 代码块具备更强的表达能力。
同时,为了方便 更好的 完成 代码演示,Theme Plume 还提供了嵌入 CodePen, Js Fiddle,Code Sandbox, Replit 的语法支持,你可以很方便的嵌入代码演示。
示例
#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